DEV Community

umzzil nng
umzzil nng

Posted on • Originally published at oraerror.com

PostgreSQL 2202E Error: Causes and Solutions Complete Guide

PostgreSQL Error 2202E: Array Subscript Error — Causes, Fixes & Prevention

PostgreSQL error code 2202E is raised when an invalid subscript is used to access an array element or slice. This typically occurs when a NULL value, an out-of-range index, or a logically incorrect slice range (e.g., lower bound greater than upper bound) is passed as an array subscript. Understanding this error is critical for anyone building data pipelines or applications that rely heavily on PostgreSQL's native array types.


Top 3 Causes

1. NULL Value Used as Array Subscript

Using NULL as an array index in a slice operation is the most common trigger for 2202E. PostgreSQL cannot resolve a NULL subscript position and raises the error immediately.

-- This will throw ERROR 2202E
SELECT (ARRAY[10, 20, 30])[NULL:2];
-- ERROR: array subscript in slice must not be null

-- Safe fix using COALESCE
SELECT (ARRAY[10, 20, 30])[COALESCE(NULL, 1):2];
-- Result: {10, 20}
Enter fullscreen mode Exit fullscreen mode

2. Invalid Slice Range (lower > upper)

When a slice range is specified where the lower bound exceeds the upper bound, PostgreSQL raises 2202E. This often happens with dynamically computed index values.

-- Triggers 2202E when lower > upper in strict mode
SELECT (ARRAY[1, 2, 3, 4, 5])[4:2];
-- May raise ERROR 2202E depending on PostgreSQL version/config

-- Safe approach: validate before slicing
DO $$
DECLARE
  lower_idx INTEGER := 4;
  upper_idx INTEGER := 2;
  arr INTEGER[] := ARRAY[1, 2, 3, 4, 5];
BEGIN
  IF lower_idx <= upper_idx THEN
    RAISE NOTICE 'Slice: %', arr[lower_idx:upper_idx];
  ELSE
    RAISE WARNING 'Invalid range: lower(%) > upper(%)', lower_idx, upper_idx;
  END IF;
END;
$$;
Enter fullscreen mode Exit fullscreen mode

3. Incorrect Subscript in Multi-Dimensional Arrays

Mixing slice notation with NULL bounds in multi-dimensional arrays is another frequent source of 2202E. Each dimension must have valid, non-NULL bounds when using slice syntax.

-- Multi-dimensional array with NULL slice bound
SELECT (ARRAY[[1,2],[3,4]])[1:2][NULL:1];
-- ERROR: array subscript in slice must not be null

-- Correct approach
SELECT (ARRAY[[1,2],[3,4]])[1:2][1:1];
-- Result: {{1},{3}}
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

Use a defensive wrapper function to handle all subscript access safely:

CREATE OR REPLACE FUNCTION safe_array_element(
  arr ANYARRAY,
  idx INTEGER,
  fallback ANYELEMENT DEFAULT NULL
)
RETURNS ANYELEMENT AS $$
BEGIN
  IF idx IS NULL
    OR arr IS NULL
    OR idx < array_lower(arr, 1)
    OR idx > array_upper(arr, 1) THEN
    RETURN fallback;
  END IF;
  RETURN arr[idx];
EXCEPTION
  WHEN SQLSTATE '2202E' THEN
    RETURN fallback;
END;
$$ LANGUAGE plpgsql;

-- Usage
SELECT safe_array_element(ARRAY[10, 20, 30], NULL, -1);
-- Result: -1 (fallback, no error)

SELECT safe_array_element(ARRAY[10, 20, 30], 2, -1);
-- Result: 20
Enter fullscreen mode Exit fullscreen mode

Prevention Tips

1. Always validate subscripts before array access.
Use array_lower(), array_upper(), and COALESCE() to ensure your index is never NULL and always within bounds before accessing any array element or slice.

-- Boundary-safe slice helper
SELECT arr[
  GREATEST(COALESCE(start_idx, 1), array_lower(arr, 1))
  :
  LEAST(COALESCE(end_idx, array_upper(arr, 1)), array_upper(arr, 1))
]
FROM (
  SELECT ARRAY[1,2,3,4,5] AS arr, NULL::INT AS start_idx, 3 AS end_idx
) t;
Enter fullscreen mode Exit fullscreen mode

2. Catch 2202E explicitly in PL/pgSQL stored procedures.
In any function that performs array operations, add an EXCEPTION block targeting SQLSTATE '2202E' to prevent cascading transaction failures and enable proper error logging in production environments.

CREATE OR REPLACE FUNCTION get_tag(tags TEXT[], idx INTEGER)
RETURNS TEXT AS $$
BEGIN
  RETURN tags[idx];
EXCEPTION
  WHEN SQLSTATE '2202E' THEN
    RAISE WARNING '2202E caught: invalid subscript % for array of length %',
      idx, array_length(tags, 1);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Enter fullscreen mode Exit fullscreen mode

Related Errors

  • 2202 — Parent class for all array subscript errors.
  • 22P02invalid_text_representation: raised when casting malformed strings to arrays.
  • 2202Dnull_value_not_allowed: occurs when NULL appears in a context that forbids it.

📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (0)