# 22016 — invalid_argument_for_nth_value_function

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

## At a glance {#at-a-glance}
`nth_value` received a non-positive ordinal. The fixed window-function path reports `argument of nth_value must be greater than zero` with SQLSTATE `22016`.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `22016` |
| Condition | `invalid_argument_for_nth_value_function` |
| Status | `active` |
| Known present by | `8.4.0` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE` |
| Aliases | `—` |

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

## Meaning {#meaning}
`window_nth_value` first reads the ordinal argument: NULL returns NULL, while an ordinal less than or equal to zero raises `22016`. A positive ordinal is then converted to a zero-based frame offset. If that row is outside the current frame, or the selected value itself is NULL, the executor returns NULL; neither case is `22016`.

## Diagnosis {#diagnosis}
Check the evaluated ordinal, the window ordering, and the frame boundaries. Distinguish an invalid non-positive argument from a valid positive argument whose target row is not in the frame. A NULL ordinal is also a NULL result path, so do not turn it into this error merely because the result is NULL.

## Response {#response}
Supply a positive ordinal when the function is meant to select a row, then adjust the ordering or frame only if the target row must be included. Preserve a NULL result when it represents a missing frame row or a NULL value. The non-positive guard raises `ERROR`; in an explicit transaction roll back or return to an existing savepoint before retrying, while autocommit can retry only the corrected statement.

## Messages {#messages}
- Primary, `ERROR`: `argument of nth_value must be greater than zero`.
- The non-positive-ordinal guard adds no DETAIL or HINT; out-of-frame and NULL-value paths return NULL instead.

## Versions {#versions}
The locked catalogue records this condition from 8.4.0; fixed source coverage is PostgreSQL 18.6. The cited behavior is the window-function implementation, not a general ordinal validator.

## Related {#related}
[`22014`](../22014/), [`22013`](../22013/)

## Sources {#sources}
[`src/backend/utils/adt/windowfuncs.c#L686-L715`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/windowfuncs.c#L686-L715) shows NULL handling, the positive-ordinal guard, the frame lookup, and the NULL return when no target row/value is available. Runtime verification is `not_run`; this source evidence is not a runtime observation. The structured [evidence record](../data/evidence/22016.json) retains the primary and scope.
