42P18 — Indeterminate datatype
42P18 — Indeterminate datatype
At a glance
42P18 (indeterminate_datatype) Type inference fails when an expression or protocol parameter has no determinate type.
| Field | Value |
|---|---|
| SQLSTATE | 42P18 |
| Condition | indeterminate_datatype |
| 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_INDETERMINATE_DATATYPE |
| Aliases | — |
Meaning
The parser cannot assign a determinate type to an expression or protocol parameter. Core 18.6 explicitly reports empty ARRAY[], and pg_analyze_and_rewrite_varparams performs a final pass that rejects every parameter still InvalidOid or UNKNOWNOID, such as $1 with no constraining context. These are different from 42P08, where inputs imply incompatible types, and 42P02, where the parameter reference itself is missing.
Diagnosis
Use the exact location or parameter number in the response. For ARRAY[], inspect the surrounding expression and cast it to the intended element type; for $n, inspect the Parse/extended-query parameter types and every context that should constrain it, then confirm the final parameter-type pass can resolve the OID. A client that sends no type OID may leave this decision to the server. A conflicting deduction is 42P08; a reference to a parameter that was not declared is 42P02.
Response
Add an explicit, semantically correct cast or supply parameter type information, then verify operators and result columns still have the intended types. Do not silence the error by casting everything to text; that can change index use and function/operator selection. Retry the parse or statement only after the corrected definition is known. If the ERROR was raised inside an explicit transaction, ROLLBACK or ROLLBACK TO a pre-error savepoint before sending the corrected statement.
Messages
Representative source messages include: message: cannot determine type of empty array; HINT: Explicitly cast to the desired type, for example ARRAY[]::integer[].; message: could not determine data type of parameter $%d. Placeholders are filled by the actual object, column, or parameter.
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
Sources
Source messages, line anchors, and evidence limits are recorded in authored evidence.
src/backend/parser/parse_expr.c:2102-2107(fixed source)src/backend/tcop/postgres.c:733-736(fixed source)