# 42P13 — Invalid function definition

> Source-backed reference for PostgreSQL SQLSTATE 42P13.
---

# 42P13 — Invalid function definition

## At a glance {#at-a-glance}

`42P13` (**invalid_function_definition**) Function, aggregate, and trigger declarations can fail validation before execution.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `42P13` |
| Condition | `invalid_function_definition` |
| Status | `active` |
| Known present by | `7.4` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_INVALID_FUNCTION_DEFINITION` |
| Aliases | `—` |

<!-- source facts: data/errcodes/42P13.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#meaning}

Function-definition validation uses this condition for incompatible declarations. Selected core paths cover a polymorphic aggregate transition type that cannot be determined (with a caller-generated internal DETAIL), a function return-type mismatch when the final statement is not a compatible SELECT or DML `RETURNING`, and trigger functions declaring arguments.

## Diagnosis {#diagnosis}

Classify the message before editing the function: aggregate transition-type inference and its dynamic DETAIL, final statement/RETURNING result versus declared return type, or trigger argument declaration. Compare the stored signature and return type with the body and the trigger contract; a non-returning DML statement or utility command is a different final-statement failure from a bad scalar coercion.

## Response {#response}

Correct the declaration or body that the message identifies. Supply a determinable aggregate transition type, make the final function statement return the declared type, and read trigger arguments through TG_NARGS/TG_ARGV instead of declaring them. Recreate or replace only after checking dependent callers. If an ERROR is raised inside an explicit transaction, `ROLLBACK` or `ROLLBACK TO` a pre-error savepoint before issuing another DDL command.

## Messages {#messages}

Representative source messages include: message: `cannot determine transition data type`; errdetail_internal: `%s`; message: `return type mismatch in function declared to return %s`; DETAIL: `Function's final statement must be SELECT or INSERT/UPDATE/DELETE/MERGE RETURNING.`; message: `trigger functions cannot have declared arguments`; HINT: `The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead.`. Placeholders are filled by the actual object, column, or parameter.

## Versions {#versions}

The locked catalogue shows this condition by PostgreSQL 7.4; behavior here is fixed to PostgreSQL 18.6 source. Catalogue presence is a range boundary, not proof that every message or feature began in that release.

## Related {#related}

- [`42P18`](../42p18/)
- [`42804`](../42804/)

## Sources {#sources}

Source messages, line anchors, and evidence limits are recorded in [authored evidence](../data/evidence/42p13.json).

- `src/backend/catalog/pg_aggregate.c:142-145` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/pg_aggregate.c#L142-L145))
- `src/backend/executor/functions.c:2222-2226` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/functions.c#L2222-L2226))
- `src/pl/plpgsql/src/pl_comp.c:493-496` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/pl/plpgsql/src/pl_comp.c#L493-L496))
