- Software and digital services
- Databases
22P02
PostgreSQL 22P02 invalid_text_representation: malformed input
Evidence linked to this decision
View source: PostgreSQL 18 Appendix A: Error CodesRisk level
Low
Usually safe to check without specialist tools.
Urgency
Medium
Quick answer
PostgreSQL SQLSTATE 22P02 (invalid_text_representation) means the input conversion routine for a target data type rejected a string literal or parameter. Check the error Position and Detail fields, test the string with pg_input_error_info, and send properly typed values or NULL.
Safety first
Stop and check this first
- Never work around 22P02 by building SQL queries through unescaped string concatenation, dropping column constraints, or converting structured columns to unconstrained text; always keep typed parameters and roll back aborted transactions with ROLLBACK before retrying.
- Because PostgreSQL often includes the rejected literal value inside the error message or Detail field for 22P02, scrub personal data, credentials, and secret tokens before exporting client or server logs.
Safe checks you can perform
- Inspect the protocol Position, Detail, and Data type name error fields
- Test the rejected text value read-only with pg_input_is_valid and pg_input_error_info
- Check expression and parameter types with pg_typeof before casting
Leave these tasks to a qualified professional
- Do not attempt this professional task: Fix parameter binding and pre-validate typed inputs in application code
- Do not attempt this professional task: Audit and cleanse staging rows with pg_input_is_valid before schema casts
What a technician must be able to justify
Technician visit
These are the steps they must carry out and show you. Tick them as they work: if steps are skipped, do not accept a part swap.
These are not instructions for opening or handling the equipment yourself. They are the checks that should support a technical conclusion.
Fix parameter binding and pre-validate typed inputs in application code
What they doThe application developer updates the query builder or driver bindings so numbers, booleans, and nulls are passed as native typed parameters (or converts blank strings with NULLIF before casting), and adds input validation matching PostgreSQL's lexical rules.
They must show youa test execution of the parameterized query and pg_input_is_valid returning true on the normalized payload.
In writingwhich parameter or field mapping caused 22P02 and the validation rule added to the application.
Audit and cleanse staging rows with pg_input_is_valid before schema casts
What they doBefore running ALTER TABLE ... TYPE or bulk INSERT ... SELECT casts, the DBA queries the source table with WHERE NOT pg_input_is_valid(col, 'target_type') inside a read-only check, cleanses or quarantines malformed rows inside a reversible transaction block, and verifies the migration.
They must show youthe count of offending rows returned by NOT pg_input_is_valid before and after data cleansing.
In writingthe exact cleansing expression applied, the backup or transaction rollback plan, and the verified post-cast column types.
Before accepting a part or repair
Nothing has been shown yet. Do not accept a part swap based on the code alone.
Follow these steps
Note: Follow the documented order. An error code identifies the affected system, but it does not prove by itself which part has failed.
Inspect the protocol Position, Detail, and Data type name error fields
- Who:
- You or your application developer reviewing the failed query log or client exception.
- How:
- Read the ErrorResponse fields returned with C = 22P02, specifically M (Message), D (Detail), P (Position, the 1-based character index into the original query string), and d (Data type name) if present, after issuing ROLLBACK if your interactive transaction block is aborted.
- Result that matters:
- The Position index and message text pinpoint which cast expression or parameter failed type conversion.
- If Position points to an explicit :
- : or CAST() expression or a specific VALUES slot, that isolates the exact target data type and input token that failed parsing.
- If the error instead reports Internal position (p) and Internal query (q) with a Where (W) stack trace, that confirms the invalid cast occurred inside a PL/pgSQL function or trigger rather than the top-level SQL string.
- Evidence to keep:
- Record the SQLSTATE 22P02 message, Detail line, Position character index, and a redacted copy of the query template.
Never paste unredacted passwords, connection strings, tokens, or personal data from failed SQL parameters into shared issue trackers.
Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL error and notice fields · PostgreSQL ROLLBACK
Test the rejected text value read-only with pg_input_is_valid and pg_input_error_info
- Who:
- Your developer or DBA running a read-only diagnostic SELECT in psql.
- How:
- Pass a redacted sample of the offending string and the target type name to SELECT pg_input_is_valid('sample', 'integer'); and SELECT * FROM pg_input_error_info('sample', 'integer'); (substituting your target type).
- Result that matters:
- Section 9.27.7 provides these data validity checking functions to test whether a string is valid input for a data type and inspect sql_error_code, message, detail, and hint without aborting a write workload.
- If pg_input_error_info returns sql_error_code 22P02, that confirms the literal string itself violates the lexical format of the target data type.
- If pg_input_error_info returns 22003 (numeric_value_out_of_range) or NULL (valid input), that rules out a 22P02 syntax failure on that sample and points to a different row or parameter in the batch.
- Evidence to keep:
- Save the output row from pg_input_error_info showing message, detail, hint, and sql_error_code.
Run only read-only SELECT checks first; do not alter table columns to unconstrained text just to silence 22P02.
Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL 18 system information functions
Check expression and parameter types with pg_typeof before casting
- Who:
- Your developer inspecting the query parameters or staging table columns.
- How:
- Run SELECT pg_typeof(expr) on the source column or parameter expression in a safe test query, and verify whether empty strings ('') or whitespace strings are arriving where SQL NULL is required.
- Result that matters:
- Knowing the resolved OID type name from pg_typeof and whether blank strings are present shows why the input conversion routine was invoked.
- If the source contains empty strings ('') or stray spaces being cast to integer, numeric, boolean, or uuid, that confirms the input must be trimmed or converted with NULLIF(trim(val), '') before casting.
- If pg_typeof shows two incompatible columns compared or joined because of misordered $1/$2 parameters, that points to a parameter-binding bug in the client code.
- Evidence to keep:
- Keep a screenshot or log of the pg_typeof result and the sanitized sample values that reproduced 22P02.
Do not concatenate raw user input into SQL strings to bypass parameter binding; always keep parameterized queries.
Evidence: PostgreSQL 18 lexical structure · PostgreSQL 18 system information functions · PostgreSQL 18 numeric types
Still not solved
If the error persists, stop here. See what the technician must do and show you.
Virtual technician
Does 22P02 still appear after these checks?
This guided flow uses the exact code and your answers to choose a test, an expected result and the next branch.
Where this code applies
A code is meaningful only inside the right product and version context.
Primary scope
- System
- Software and digital services
- Brand
- PostgreSQL
- Product type
- Databases
Known code variants
- invalid_text_representation
- PostgreSQL 22P02
- SQLSTATE 22P02
What it means
In Appendix A of the PostgreSQL 18 documentation, 22P02 maps to invalid_text_representation under Class 22 (Data Exception). When a query casts a string via type 'string', 'string'::type, CAST('string' AS type), or assigns text to a typed table column, the server passes that text to the data type's input conversion routine. If the characters do not match the lexical grammar of the target type, such as letters or an empty string sent to an integer column, the routine aborts the statement with 22P02. The code alone proves malformed input text, not table corruption or a server fault.
Warnings and stop conditions
- Mediumeditorial warning
Never work around 22P02 by building SQL queries through unescaped string concatenation, dropping column constraints, or converting structured columns to unconstrained text; always keep typed parameters and roll back aborted transactions with ROLLBACK before retrying.
Evidence: PostgreSQL ROLLBACK · PostgreSQL 18 lexical structure
- Loweditorial warning
Because PostgreSQL often includes the rejected literal value inside the error message or Detail field for 22P02, scrub personal data, credentials, and secret tokens before exporting client or server logs.
Evidence: PostgreSQL error and notice fields
Symptoms and causes
Probable causes · in order
- Non-numeric or empty string passed to an integer or numeric input routineCommon
PostgreSQL integer types (smallint, integer, bigint) require whole numbers without embedded spaces, currency signs, or blank text, while numeric constants allow only digits, a decimal point, an exponent marker, or visual underscores between digits (or quoted Infinity, -Infinity, and NaN).
Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL 18 lexical structure · PostgreSQL 18 numeric types
- Untyped parameter or CSV field containing invalid syntax for a structured typePossible
When an application driver, COPY load, or JSON extraction passes an unvalidated text token into a typed column or explicit cast, any character sequence rejected by the target type's input conversion routine triggers SQLSTATE 22P02.
Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL 18 lexical structure · PostgreSQL 18 system information functions
- Double quotes or shifted placeholders supplying an unexpected string tokenPossible
Because SQL uses single quotes for string constants and double quotes for delimited identifiers, or because positional parameters ($1, $2) are bound in the wrong order, a column name or text field can be routed into a non-text cast.
Evidence: PostgreSQL error and notice fields · PostgreSQL 18 lexical structure
Sources and technical references
- 1
PostgreSQL 18 Appendix A: Error Codes
PostgreSQL Global Development Group · 2026 · official_doc
- 2
PostgreSQL error and notice fields
PostgreSQL Global Development Group · 2026 · official_doc
Was this entry useful?