# 2203B — sql_json_number_not_found

> Source-backed reference for PostgreSQL SQLSTATE 2203B.
---

# 2203B

## At a glance {#at-a-glance}
A unary jsonpath arithmetic operator needs a numeric operand but receives another item type. This is the unary-operator boundary, separate from numeric conversion methods.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `2203B` |
| Condition | `sql_json_number_not_found` |
| 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_SQL_JSON_NUMBER_NOT_FOUND` |
| Aliases | `—` |

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

## Messages {#messages}
The fixed unary branch reports:

`operand of unary jsonpath operator %s is not a numeric value`

## Meaning {#meaning}
`executeUnaryArithmExpr` walks the operand sequence and accepts every numeric scalar item, applying the unary function to each. A non-numeric item is skipped only when both `!found` and `!hasNext` hold: that is a terminal existence-style evaluation that is not collecting results. Otherwise the 2203B guard is reached, including ordinary result collection at a terminal step. The evaluator may unwrap an array in lax mode. Numeric item methods such as `.number()` or `.integer()` use 22036 instead.

## Diagnosis {#diagnosis}
Read the operator name and the full item sequence immediately before the unary operator. Check which items are numeric, whether lax unwrapping changed the sequence, and whether the caller is collecting results or only testing existence at a terminal step. Do not interpret this as an out-of-range numeric value or as a failed numeric conversion method.

## Response {#response}
Constrain the path to the intended numeric sequence, normalize each JSON value, or choose an operation that accepts the actual type. Treat the terminal existence/no-collection optimization as a separate documented behavior; ordinary result collection still requires every processed item to be numeric. 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 unary arithmetic branch is PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`22036`](../22036/), [`22038`](../22038/), [`22012`](../22012/)

## Sources {#sources}
The complete unary arithmetic sequence and non-numeric guard are [`jsonpath_exec.c#L2158-2221`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L2158). The shared strict/lax and throw-return macros are [`jsonpath_exec.c#L235-249`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L235). The structured [evidence record](../data/evidence/2203b.json) binds the operator primary and terminal-path boundary; no natural runtime was run.
