# 22038 — singleton_sql_json_item_required

> Source-backed reference for PostgreSQL SQLSTATE 22038.
---

# 22038

## At a glance {#at-a-glance}
A SQL/JSON path operation expected one result of a required type, but received another cardinality or type. The fixed paths cover a singleton boolean result and the two numeric operands of binary jsonpath arithmetic; the SQL function and the `@@` operator have different default silent behavior.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `22038` |
| Condition | `singleton_sql_json_item_required` |
| Status | `active` |
| Known present by | `12.0` |
| Locked snapshots | `12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED` |
| Aliases | `—` |

<!-- source facts: data/errcodes/22038.json -->
<!-- END SQLSTATE FACTS -->

## Messages {#messages}
Representative primary texts are:

| Guard | Primary |
| --- | --- |
| Non-singleton or non-boolean `jsonb_path_match` result in throwing mode | `single boolean result is expected` |
| Left binary arithmetic operand is not one numeric item | `left operand of jsonpath operator %s is not a single numeric value` |
| Right binary arithmetic operand is not one numeric item | `right operand of jsonpath operator %s is not a single numeric value` |

## Meaning {#meaning}
`jsonb_path_match_internal` treats exactly two C arguments as the `@@` operator path: `jsonb_path_match_opr` leaves `silent=true`, so a non-singleton or non-boolean result becomes NULL. The SQL function is declared as `jsonb_path_match(target, path, vars DEFAULT '{}', silent DEFAULT false)`; even a call written with two SQL arguments is expanded with both defaults, so it is non-silent and can raise 22038 unless the caller supplies `silent=true`. A four-argument call follows its supplied `silent` value. A single JSON null returns SQL NULL. Binary arithmetic separately evaluates each operand sequence, and both sides must contain exactly one numeric item. The shared evaluator may unwrap arrays in lax mode before this singleton check.

## Diagnosis {#diagnosis}
Identify whether the syntax is the `@@` operator or the `jsonb_path_match` function, and inspect the actual argument/default expansion before interpreting a NULL result. A path that yields several values, a non-boolean match result, or a left/right item that is not numeric belongs to this singleton/type boundary. Distinguish it from 22034 JSON_QUERY/JSON_VALUE cardinality, 2203F scalar-type enforcement, and 22036 numeric item-method conversion.

## Response {#response}
Narrow the path or select one item explicitly. For binary arithmetic, make both operands resolve to one numeric item. Choose `@@` when its suppressing behavior is intended, or call `jsonb_path_match(..., false)` when a mismatch should remain an ERROR; use `silent=true` only when NULL is the intended result. If an ERROR occurred in an explicit transaction, roll back or roll back to the existing savepoint before retrying; autocommit can retry the corrected action.

## Versions {#versions}
The locked catalogue records this condition from 12.0; the fixed match and binary-arithmetic paths are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`22034`](../22034/), [`2203F`](../2203f/), [`22036`](../22036/)

## Sources {#sources}
The match wrapper and singleton guard are [`jsonpath_exec.c#L453-491`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L453); binary arithmetic singleton checks are [`#L2087-2155`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L2087); the shared strict/lax and throw-return macros are [`#L235-249`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L235). The SQL defaults are fixed in [`system_functions.sql#L539-544`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/system_functions.sql#L539), the direct function and `@@` implementation signatures in [`pg_proc.dat#L10520-10522`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/catalog/pg_proc.dat#L10520) and [`#L10547-10549`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/catalog/pg_proc.dat#L10547), and the operator binding in [`pg_operator.dat#L3262-3264`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/catalog/pg_operator.dat#L3262). The structured [evidence record](../data/evidence/22038.json) keeps both paths and exact primaries; no natural runtime was run.
