22P02
Read PG 18 manual ↗invalid_text_representation
- SQLSTATE
- 22P02
- Condition name
- invalid_text_representation
- Class
- Data Exception
- Source macro
- ERRCODE_INVALID_TEXT_REPRESENTATION
- Evidence
- Observed at runtime in the source evidence
English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗
At a glance
22P02 means a text input routine cannot interpret a value as the requested type. This page selects the ordinary integer input path and also marks the COPY/text boundary; COPY, enum, extension, and contrib callers can use different primary messages.
Meaning
For a cast, assignment, or text COPY field, the destination type's input routine decides whether text is valid. PostgreSQL 18.6 emits invalid input syntax for type integer: "%s", while the locked PostgreSQL 10.23 source uses invalid input syntax for integer: "%s"; both are dynamic templates, not a universal localized string. Other fixed callers include COPY reject-limit reporting, enum input, and extension validation, so the primary text and context can differ.
Diagnosis
Record the destination type, the exact value after client encoding and parameter binding, and whether the operation is a cast, assignment, text COPY field, enum input, or another type wrapper. Distinguish malformed text (22P02) from numeric range overflow (22003), invalid date/time syntax (22007), invalid binary representation (22P03), and a malformed COPY file/header or framing (22P04). Do not diagnose a binary COPY payload with the text-input message alone.
Response
Validate at the input boundary and preserve the intended target type. Retry only after correcting the value; do not silently truncate or turn the value into NULL unless that is the explicit business rule. In an explicit transaction, an input ERROR leaves the transaction aborted (25P02); use ROLLBACK or a savepoint such as ROLLBACK TO SAVEPOINT convert_input before continuing. A COPY error likewise requires transaction recovery before another command.
Observed diagnostics
The fixed ordinary integer path has ERROR severity and the version-specific primary templates above. The selected runtime records the exact values: "not-an-integer" produced 22P02, and a valid "42" returned 42 on the same autocommit session.
Representative case
The shared registry sends one invalid text cast in autocommit, inspects the real diagnostic and IDLE state, then sends a valid integer text on the same connection. That observed recovery is different from an explicit transaction, where the client must roll back or roll back to a savepoint before continuing. The page uses the registry SQL; the runner substitutes no hidden second definition.
SELECT 'not-an-integer'::integer;
SELECT '42'::integer
The selected PostgreSQL 18.6 and 10.21 runs passed SQLSTATE, severity, state or disconnect recovery, repair, cleanup, and isolated-target stop assertions. See case JSON and authored evidence.
Versions
The locked catalogue records 22P02 from 7.4 through the listed snapshots. The bounded runtime comparison passed on 18.6 and 10.21, with the primary wording differing as shown; that does not generalize every 22P02 caller or every intermediate implementation.
Sources
src.errcodes.18.6—src/backend/utils/errcodes.txtat724edf9bde9d356724ad384a2e196edc3c9f80f7; blob SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba(source).src.invalid-integer.18.6—src/backend/utils/adt/numutils.cat724edf9bde9d356724ad384a2e196edc3c9f80f7; blob SHA-2569018d559d8a2b04f6d3fa8fedeb754fc5f1f8cd8594292e6adc5108e8f97f1bf(source).src.invalid-integer.10.23—src/backend/utils/adt/numutils.cat02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4; blob SHA-2566cb3fd7e4b38a66c16f2cc4a3de0c52ce44e01dd22edd3dd9340d2a8faea0d35(source).src.copy-text.18.6— the fixed text-COPY conversion/reject-limit path insrc/backend/commands/copyfrom.cat lines 1169-1172 (source).src.calls.REL_18_6/src.calls.REL_10_23— fixed call scans, SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf/00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c.manifest.22P02/snippet-registry.22P02— hashes are recorded inevidence/22P02.jsonand each selected runtime record.
Source evidence
Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.
22P02 is invalid_text_representation in SQLSTATE Class 22.
Method: Read fixed definition.
The cited PostgreSQL 18.6 source paths support the representative mechanisms and message boundaries described.
Method: Read complete fixed source contexts.
Limits: Source confirmation is not natural runtime.
The locked catalogue records 22P02 from 7.4; that boundary does not prove exact implementation introduction.
Method: Use catalogue boundary.
The selected ordinary cast path reports invalid integer text through the numeric input routine; PostgreSQL 18 and 10 use different fixed wording around the type name.
Method: Read fixed numutils.c source-call records and compare selected runtime diagnostics.
Limits: This is one integer-input path; COPY, enum, extension, and contrib callers can use different 22P02 messages.
The invalid_integer_text case passed on isolated PostgreSQL 18.6 and 10.21 targets, with IDLE recovery and a same-session valid value of 42.
Method: Execute the shared registry and inspect SQLSTATE, severity, IDLE state, repair, cleanup, and target stop.
Limits: Scope is limited to the integer cast statements, psycopg, and the two selected versions.
- src/backend/utils/errcodes.txt · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/copyfrom.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - contrib/file_fdw/file_fdw.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - contrib/isn/isn.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/extension.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/utils/adt/numutils.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/utils/adt/numutils.c · REL_10_23 ·
02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4 verify/cases/22P02/cases.json· ·verify/cases/22P02/snippets.json· ·raw/calls/REL_18_6.jsonl· REL_18_6 ·raw/calls/REL_10_23.jsonl· REL_10_23 ·
Message templates
ERROR · message.0
Primary
skipped more than REJECT_LIMIT (%" PRId64 ") rows due to data type incompatibility
ERROR · message.1
Primary
cannot cast EAN13(%s) to %s for number: "%s"
ERROR · message.2
Primary
invalid character in extension owner: must not contain any of "%s"
ERROR · message.integer-input.18.6
Primary
invalid input syntax for type integer: "%s"
ERROR · message.integer-input.10.23
Primary
invalid input syntax for integer: "%s"
Reproduction & repair cases
invalid_integer_text · PG 10, 18
Preconditions
- A runner-owned disposable target is provisioned.
Trigger: Cast non-numeric text to integer, then cast a valid integer text on the same connection.
Expected assertions
- SQLSTATE is 22P02 with ERROR severity
- The primary diagnostic identifies invalid integer input and the supplied text
- The failed autocommit session remains IDLE
- A valid integer text returns 42 afterward
Repair: Validate or reject input before casting; if the input is valid, cast it to the intended type and keep the business validation separate from syntax recovery.
Cleanup: Close all runner connections and drop the case schema with an owner connection.
Recorded runtime evidence
18.6 (Homebrew) · passed
Run: ops-22p02-latest-1
{
"diagnostic": {
"text": "invalid input syntax for type integer: \"not-an-integer\"\nLINE 1: SELECT 'not-an-integer'::integer\n ^",
"context": null,
"severity": "ERROR",
"sqlstate": "22P02",
"table_name": null,
"column_name": null,
"schema_name": null,
"source_file": "numutils.c",
"source_line": "618",
"message_hint": null,
"datatype_name": null,
"exception_type": "InvalidTextRepresentation",
"internal_query": null,
"message_detail": null,
"constraint_name": null,
"message_primary": "invalid input syntax for type integer: \"not-an-integer\"",
"source_function": "pg_strtoint32_safe",
"internal_position": null,
"statement_position": "8",
"severity_nonlocalized": "ERROR"
},
"target_type": "integer",
"invalid_text": "not-an-integer",
"repair_value": 42,
"failed_status": "IDLE",
"repair_status": "IDLE",
"connection_autocommit": true
}10.21 (Debian 10.21-1.pgdg90+1) · passed
Run: ops-22p02-pg10-1
{
"diagnostic": {
"text": "invalid input syntax for integer: \"not-an-integer\"\nLINE 1: SELECT 'not-an-integer'::integer\n ^",
"context": null,
"severity": "ERROR",
"sqlstate": "22P02",
"table_name": null,
"column_name": null,
"schema_name": null,
"source_file": "numutils.c",
"source_line": "62",
"message_hint": null,
"datatype_name": null,
"exception_type": "InvalidTextRepresentation",
"internal_query": null,
"message_detail": null,
"constraint_name": null,
"message_primary": "invalid input syntax for integer: \"not-an-integer\"",
"source_function": "pg_atoi",
"internal_position": null,
"statement_position": "8",
"severity_nonlocalized": "ERROR"
},
"target_type": "integer",
"invalid_text": "not-an-integer",
"repair_value": 42,
"failed_status": "IDLE",
"repair_status": "IDLE",
"connection_autocommit": true
}Definition snapshot: english-manuals:7704b5471e7f1492fc8525d87c6… · English manual source