This error occurs when using incorrect subscript syntax to access JSON or JSONB data in PostgreSQL. The subscript must be an integer for arrays or a string for objects, and the data type must match the operation.
PostgreSQL enforces strict type checking when accessing JSON and JSONB elements using subscript notation (e.g., `jsonb_column['key']` or `jsonb_column[0]`). This error indicates a mismatch between the subscript type and the actual JSON structure. It typically occurs when attempting to access a JSON object with an integer subscript, accessing a JSON array with a string subscript, using NULL as a subscript, or attempting to traverse through non-object/non-array values in a path expression.
Use jsonb_typeof() to determine the actual type of your JSON data. This function returns 'object', 'array', 'string', 'number', 'boolean', or 'null'. This helps you understand whether your data is actually an array or an object:
SELECT jsonb_typeof(json_column) FROM your_table LIMIT 1;Also inspect the actual JSON content to see its structure:
SELECT json_column FROM your_table LIMIT 1;For JSON arrays, use integer subscripts starting from 0. Negative indices count backwards from the end:
-- Correct: accessing array element at index 0
SELECT json_array[0] FROM your_table;
-- Correct: accessing last element using negative index
SELECT json_array[-1] FROM your_table;
-- Wrong: using string subscript on array
SELECT json_array['0'] FROM your_table; -- INVALIDFor JSON objects, use string subscripts enclosed in single quotes:
-- Correct: accessing object value by string key
SELECT json_object['key_name'] FROM your_table;
-- Correct: nested object access
SELECT json_object['level1']['level2'] FROM your_table;
-- Wrong: using integer subscript on object
SELECT json_object[0] FROM your_table; -- INVALIDVerify that your subscript value is not NULL and that intermediate traversal paths exist:
-- Protect against NULL subscripts
SELECT json_object[COALESCE(my_key, 'default')] FROM your_table;
-- Check if the path exists before accessing deeper levels
SELECT json_object['key'] FROM your_table WHERE json_object['key'] IS NOT NULL;
-- Use jsonb_path_exists() to test path existence first
SELECT json_object FROM your_table
WHERE jsonb_path_exists(json_object, '$.key.subkey');When updating JSONB values, use subscript notation in the SET clause. This is cleaner than jsonb_set() and was introduced in PostgreSQL 14:
-- PostgreSQL 14+: Direct subscript assignment
UPDATE your_table SET json_column['key'] = 'new_value'::jsonb
WHERE id = 1;
-- This automatically creates intermediate objects if they don't exist
UPDATE your_table SET json_column['level1']['level2'] = 'value'::jsonb
WHERE id = 1;
-- For PostgreSQL < 14, use jsonb_set() instead
UPDATE your_table SET json_column = jsonb_set(json_column, '{key}', 'new_value'::jsonb)
WHERE id = 1;When comparing JSONB values, ensure both sides of the comparison are JSONB type:
-- Correct: both sides are JSONB
SELECT * FROM your_table WHERE json_column['status'] = '"active"'::jsonb;
-- Note: JSON strings need double-quotes inside the jsonb value
-- The outer quotes define the literal, inner quotes are part of the JSON
SELECT * FROM your_table WHERE json_column['name'] = '"John"'::jsonb;
-- Avoid type mismatch
SELECT * FROM your_table WHERE json_column['status'] = 'active'; -- May failPostgreSQL 14 introduced native JSONB subscript support, making JSON manipulation much cleaner. Prior versions required jsonb_set() and -> operators. If you need to support older PostgreSQL versions, use json_extract_path() and json_extract_path_text() functions instead of subscript notation. For complex JSON transformations, consider the jsonb_modify extension or use application-level parsing. When dealing with very large JSON documents, be aware that subscript operations traverse the entire JSON structure, which can impact performance on deeply nested objects.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL