# 54023 — too_many_arguments

> Source-backed reference for PostgreSQL SQLSTATE 54023.
---

# 54023

## At a glance {#at-a-glance}
`54023` is the argument-count limit for functions, procedures, aggregates, and set-returning calls. Fixed paths protect catalog arrays, parser nodes, and executor `FunctionCallInfo` storage, and report the actual compile-time limit with plural-aware messages.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `54023` |
| Condition | `too_many_arguments` |
| 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_TOO_MANY_ARGUMENTS` |
| Aliases | `—` |

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

## Meaning {#meaning}
The fixed build defines `FUNC_MAX_ARGS` as 100 in `pg_config_manual.h`; the source notes a practical upper bound near 600 and requires a full backend (including C functions) recompile if it changes. Function definitions count input parameters and explicitly do not count output arguments. Aggregate definitions and aggregate calls use `FUNC_MAX_ARGS - 1` so transition/final functions remain representable. Procedure/function parser and executor guards cover explicit arguments plus default arguments, SRFs, and stored window expressions. The caller and object kind determine the repair.

## Messages {#messages}

| Source path | Exact primary template (singular / plural) | Count passed to `%d` |
| --- | --- | --- |
| `pg_proc.c` function definition | `functions cannot have more than %d argument` / `functions cannot have more than %d arguments` | Compare `parameterCount` (the input-parameter array length; output parameters are excluded) with `FUNC_MAX_ARGS`; `%d` receives `FUNC_MAX_ARGS` (100) |
| `functioncmds.c` procedure call | `cannot pass more than %d argument to a procedure` / `cannot pass more than %d arguments to a procedure` | Compare `nargs = list_length(fexpr->args)` with `FUNC_MAX_ARGS`; `%d` receives `FUNC_MAX_ARGS` |
| `parse_func.c`, `execExpr.c`, `execSRF.c`, and `nodeWindowAgg.c` function/SRF/window call | `cannot pass more than %d argument to a function` / `cannot pass more than %d arguments to a function` | Compare `list_length(fargs)`, `nargs`, `list_length(sexpr->args)`, or `perfuncstate->numArguments` with `FUNC_MAX_ARGS`; `%d` receives `FUNC_MAX_ARGS` |
| `pg_aggregate.c` aggregate definition/call | `aggregates cannot have more than %d argument` / `aggregates cannot have more than %d arguments` | Compare `numArgs` with `FUNC_MAX_ARGS - 1`; `%d` receives 99, leaving a slot for transition/final functions |

These are `errmsg_plural` groups, so clients should preserve the server's singular/plural rendering and the reported limit instead of searching only for one hand-written string.

## Diagnosis {#diagnosis}
Record whether the failure is CREATE/definition time or invocation time, and whether the object is a function, procedure, aggregate, SRF, or window aggregate. Count explicit arguments and parser-expanded defaults; for an aggregate use the stricter `FUNC_MAX_ARGS - 1` boundary. Preserve the exact singular/plural primary and maximum from the message, and check whether a stored view/plan was made by a binary with a different `FUNC_MAX_ARGS`.

## Response {#response}
Reduce the argument list, group related values into a composite or documented record type, or redesign the function boundary. For a procedure or aggregate definition, change the signature and dependent callers together; do not silently drop arguments, count output arguments as inputs, or assume aggregate and ordinary-function calls share the same limit. Changing `FUNC_MAX_ARGS` is a build-wide compatibility decision, not a session setting. If an `ERROR` occurs inside an explicit transaction, use `ROLLBACK` or `ROLLBACK TO SAVEPOINT` before retrying; in autocommit, retry only after the definition or call has been changed to fit the fixed count.

## Versions {#versions}
The locked catalogue records this condition from 7.4; cited macro, catalog, parser, executor, aggregate, and SRF paths are PostgreSQL 18.6 source. No oversized signature or call was created.

## Related {#related}
[`54011`](../54011/), [`54000`](../54000/), [`42883`](../42883/)

## Sources {#sources}
[`src/backend/catalog/pg_proc.c#L156-L161`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/pg_proc.c#L156)

[`src/backend/commands/functioncmds.c#L2261-L2266`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/functioncmds.c#L2261)

[`src/backend/executor/execExpr.c#L2727-L2732`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/execExpr.c#L2727)

[`src/backend/executor/execSRF.c#L716-L721`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/execSRF.c#L716)

[`src/include/pg_config_manual.h#L31-L43`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/pg_config_manual.h#L31)

[`src/backend/catalog/pg_aggregate.c#L121-L132`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/pg_aggregate.c#L121)

[`src/backend/parser/parse_func.c#L129-L142`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_func.c#L129)

[`src/backend/executor/nodeWindowAgg.c#L1042-L1054`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeWindowAgg.c#L1042)

The structured [evidence record](../data/evidence/54023.json) records fixed messages and the source/runtime boundary.
