PG
PRO
42P18ERRORTier 1 — Safe✅ HIGH confidence

could not determine data type of parameter $N

Category: Indeterminate DatatypeVersions: All Postgres versions

What this means

The query parser was unable to infer the type of a parameter placeholder ($1, $2, etc.) or an untyped literal because there is insufficient context in the query to determine what type to use.

Why it happens

  1. 1Using a parameter placeholder ($1) in a position where the type cannot be inferred from surrounding context
  2. 2Passing an untyped NULL without a cast in a UNION or CASE expression
  3. 3Prepared statements where the parameter appears only in a VALUES list without a column type context
  4. 4Using $1 in a standalone SELECT without comparison or assignment context

How to reproduce

A prepared statement parameter has no type context for inference.

trigger — this will ERROR
PREPARE test_stmt AS SELECT $1;
EXECUTE test_stmt('hello');
ERROR: could not determine data type of parameter $1

Fix 1: Add an explicit type cast to the parameter

When you know the expected type of the parameter.

fix
PREPARE test_stmt AS SELECT $1::TEXT;
EXECUTE test_stmt('hello');

-- In application code (e.g. node-postgres):
-- const res = await client.query('SELECT $1::text', ['hello']);

Why this works

The parser infers parameter types by examining the expression context (e.g., a comparison with a typed column). When no context exists, an explicit cast (::TEXT, ::INTEGER) supplies the type directly, allowing the parser to record the type in the parameter descriptor.

Fix 2: Provide a type context through comparison or assignment

When the parameter is used in a query with a typed column.

fix
PREPARE find_user AS SELECT * FROM users WHERE email = $1;
EXECUTE find_user('alice@example.com');
-- email is TEXT, so $1 is inferred as TEXT

Why this works

The parser walks the expression tree and uses type unification to propagate known types to adjacent parameters. A comparison with a typed column (email TEXT) tells the parser that $1 must also be TEXT, resolving the indeterminate type.

What not to do

Use string interpolation to embed values directly in SQL strings

Why it's wrong: Bypasses the parameterised query mechanism and opens the code to SQL injection vulnerabilities.

Sources

📚 Official docs: https://www.postgresql.org/docs/current/errcodes-appendix.html

📚 Feature docs: https://www.postgresql.org/docs/current/sql-prepare.html

🔧 Source ref: src/backend/parser/parse_param.c — transformParamRef()

📖 Further reading: PREPARE

Confidence assessment

✅ HIGH confidence

Stable and well-documented. Type inference for parameters is consistent across versions. Edge case: anonymous prepared statements sent via the extended query protocol may produce this error at the protocol level rather than as a SQL error, with a different presentation in some client libraries.

See also

📄 Reference pages

PREPAREType CastingExtended Query Protocol
⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →