When PostgreSQL encounters a function or operator invocation that exceeds the maximum supported number of arguments, it raises:
ERROR: cannot pass more than 100 arguments to a function
SQLSTATE: 54023
The SQLSTATE code is 54023, and the condition name is too_many_arguments. This error belongs to error class 54 — Program Limit Exceeded — which covers hard limits enforced by PostgreSQL itself rather than violations of data constraints.
What This Error Means
Error class 54 covers situations where a PostgreSQL internal limit has been reached. Code 54023 specifically fires when the argument count passed to a function or operator call exceeds PostgreSQL's built-in ceiling. As of current PostgreSQL releases, that ceiling is 100 arguments per function call.
This limit is not a configuration parameter — it is compiled into PostgreSQL as part of how function call infrastructure (FunctionCall structures) is laid out internally. No postgresql.conf setting can raise it.
When the error is raised, the current statement fails and the transaction is marked as aborted (if you are inside an explicit transaction). You must roll back before issuing further DML. The error occurs at parse or plan time, so no data is modified before it is raised.
The same limit applies to user-defined functions (SQL, PL/pgSQL, PL/Python, etc.), built-in functions, and aggregate function signatures. It also applies to operators that are backed by functions, though operators by definition take one or two operands, so they never trigger this error in practice.
Common Causes
Dynamically constructed function calls with unbounded argument lists. Application code that builds a function call by iterating over a collection and appending arguments (e.g., passing every column value individually) can silently grow past 100 when the dataset is larger than expected.
Overloaded or variadic-style wrapper functions called with too many arguments. Functions declared with a variadic parameter (e.g.,
f(VARIADIC args text[])) still enforce the 100-argument limit on the direct call form. Passing more than 100 literal arguments at the call site triggers the error even though the function itself accepts an array of arbitrary length.Generated SQL from ORMs or query builders. Some ORMs generate
IN (...)clauses or multi-rowVALUESinserts as function calls, or build parameterized queries where each bind parameter becomes a positional argument, inadvertently hitting the limit.Hand-written SQL using
CONCAT,COALESCE,GREATEST,LEAST, or similar variadic built-ins with very long argument lists. These functions accept a variadic argument list subject to the same 100-argument cap.
How to Fix too_many_arguments
Pass an array instead of individual arguments. Refactor the function to accept an array type and pass a single array argument constructed with
ARRAY[...]orARRAY(SELECT ...):-- Instead of f(a1, a2, ..., a101) CREATE OR REPLACE FUNCTION process_items(items text[]) RETURNS void LANGUAGE plpgsql AS $$ BEGIN -- iterate over items[] END; $$; SELECT process_items(ARRAY['val1', 'val2', /* ... */]);Use a temporary table or CTE to pass bulk data. When a function needs to process many rows, insert them into a temporary table and let the function query it, rather than passing each value as an argument:
CREATE TEMP TABLE bulk_input(val text) ON COMMIT DROP; INSERT INTO bulk_input VALUES ('val1'), ('val2') /*, ... */; SELECT process_from_table(); -- function reads from bulk_inputReplace long
IN (...)lists with= ANY(ARRAY[...])or a subquery. Many ORMs generating largeINlists can be switched to array comparisons, which do not count as multi-argument function calls:-- Avoid: WHERE id IN (1, 2, 3, ..., 101) -- Use: WHERE id = ANY(ARRAY[1, 2, 3, /* ... */ 101]) -- or better, a join to a VALUES list: WHERE id IN (SELECT unnest(ARRAY[1, 2, 3, /* ... */]))Break the call into batches at the application layer. If the function signature cannot be changed, chunk the argument list into groups of at most 100 and invoke the function once per chunk.
Use
VARIADICcorrectly with an array literal. If the function is declaredVARIADIC, pass the arguments as an array using theVARIADICkeyword at the call site to bypass individual-argument counting:SELECT my_variadic_func(VARIADIC ARRAY['a', 'b', /* ... up to millions */]);Note: this form passes a single array argument and does not trigger the 100-argument limit.
Additional Information
- The 100-argument limit has been present since very early PostgreSQL versions and has not changed across PostgreSQL 9.x through 16.x/17.x.
- Related class
54SQLSTATE codes include54001(statement_too_complex) and54011(too_many_columns). All represent compiled-in program limits. - Most PostgreSQL client drivers (libpq, psycopg2/3, asyncpg, node-postgres, JDBC) surface this error as a server-side
PSQLExceptionor equivalent with the54023SQLSTATE. The message text is standardized:"cannot pass more than 100 arguments to a function". - ORMs such as SQLAlchemy, Hibernate, and ActiveRecord can silently generate calls that approach this limit when processing large collections — add monitoring or assertions in your data layer if argument counts are dynamic.
Frequently Asked Questions
Can I increase the 100-argument limit in postgresql.conf?
No. The limit is a compile-time constant in PostgreSQL source code (FUNC_MAX_ARGS, set to 100 in pg_config_manual.h). It cannot be changed without recompiling PostgreSQL from source. The correct fix is to redesign the function interface to use arrays or tables instead of many positional arguments.
Does this error occur with PL/pgSQL functions or only built-ins? It applies to all function types — SQL functions, PL/pgSQL, PL/Python, PL/Perl, C functions, and built-ins. The limit is enforced at the function call infrastructure level, not per language.
My ORM is generating this error but I never wrote a function call. Why?
Some ORMs translate large WHERE id IN (...) lists into parameterized queries where each value becomes a positional bind parameter ($1, $2, ...). If there are more than 100 values, the generated function call (an internal operator or function backing the IN expression) exceeds the limit. Switch to = ANY($1::int[]) with a single array parameter instead.
Is 54023 the same as a syntax error?
No. Syntax errors in PostgreSQL have SQLSTATE 42601 (class 42 — Syntax Error or Access Rule Violation). SQLSTATE 54023 is a program limit error (class 54) raised after the query is successfully parsed, when the planner or executor detects the argument count violation.