# 2203C — sql_json_object_not_found

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

# 2203C

## At a glance {#at-a-glance}
An object-only JSON path accessor or `.keyvalue()` method received a non-object item. Wildcard member access and object key/value expansion use this structural guard.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `2203C` |
| Condition | `sql_json_object_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_OBJECT_NOT_FOUND` |
| Aliases | `—` |

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

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

| Guard | Primary |
| --- | --- |
| Wildcard member accessor receives a non-object | `jsonpath wildcard member accessor can only be applied to an object` |
| `.keyvalue()` receives a non-object | `jsonpath item method .%s() can only be applied to an object` |

## Meaning {#meaning}
The wildcard member branch accepts a JSON object; its non-object structural mismatch can be ignored when `jspIgnoreStructuralErrors` is true, and an array may be auto-unwrapped in lax mode. `.keyvalue()` may likewise auto-unwrap an array before it requires an object container, but its direct non-object guard uses `RETURN_ERROR`: throwing versus returning `jperError` follows `jspThrowErrors`, as selected by the caller's silent or ON ERROR handling. Lax mode itself does not suppress this direct `.keyvalue()` guard. Named member access with a missing key is 2203A, while array-only access is 22039.

## Diagnosis {#diagnosis}
Use the primary to identify the wildcard accessor or item method, then inspect the current item type. Distinguish an object receiver that lacks a named key from a scalar/array receiver that cannot support object expansion. Check lax auto-unwrap and structural-error handling before treating the result as a missing item.

## Response {#response}
Select an object, normalize the input shape, or branch before applying the object-only operation. For wildcard access, use lax structural suppression only when dropping a non-object branch is intended. For `.keyvalue()`, lax can only unwrap an array first; a remaining non-object follows the direct throw/silent/ON ERROR path, so do not assume lax suppression will ignore it. 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 object-only accessor and `.keyvalue()` guards are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`22039`](../22039/), [`2203A`](../2203a/), [`22037`](../22037/)

## Sources {#sources}
The wildcard member guard is [`jsonpath_exec.c#L852-874`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L852), and `.keyvalue()` checks its object container at [`#L2806-2828`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/jsonpath_exec.c#L2806). 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/2203c.json) binds both object-only primaries; no natural runtime was run.
