# 2201W — invalid_row_count_in_limit_clause

> Source-backed reference for PostgreSQL SQLSTATE 2201W.
---

# 2201W

## At a glance {#at-a-glance}
A LIMIT or FETCH row count fails a form-specific guard. Fixed paths report `LIMIT must not be negative`; the parser separately rejects a literal NULL row count in `FETCH FIRST ... WITH TIES`.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `2201W` |
| Condition | `invalid_row_count_in_limit_clause` |
| 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_ROW_COUNT_IN_LIMIT_CLAUSE` |
| Aliases | `—` |

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

## Representative messages {#messages}
The representative guards use these primary texts:

| Path | Primary |
| --- | --- |
| ordinary LIMIT with a negative count | `LIMIT must not be negative` |
| literal NULL in `FETCH FIRST ... WITH TIES` | `row count cannot be null in FETCH FIRST ... WITH TIES clause` |

## Meaning {#meaning}
The executor evaluates an ordinary LIMIT count: NULL is interpreted as no count (`LIMIT ALL`), zero is valid and returns no rows, and a negative value emits 2201W. The parser has a separate guard for an unadorned NULL constant in `FETCH FIRST ... WITH TIES`; it is not a blanket rule that every nullable LIMIT expression has the same behavior. OFFSET is handled by 2201X.

## Diagnosis {#diagnosis}
Identify whether the message came from an ordinary LIMIT evaluation or the `WITH TIES` parser rule, then inspect the evaluated expression and its type. Keep NULL-without-ties, literal NULL-with-ties, zero, and negative values separate. A hidden expression can pass the parser’s narrow `A_Const` check, so classify the resulting behavior from the actual statement and message.

## Response {#response}
For ordinary LIMIT, use a non-negative count or NULL when an unlimited result is intended. For `WITH TIES`, provide a non-NULL row count accepted by that syntax. If the negative-count or parser ERROR occurred inside an explicit transaction, roll back or roll back to the existing savepoint before retrying; autocommit can retry the corrected statement.

## Versions {#versions}
The locked catalogue records this condition from 8.4.0; the fixed source paths here are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`2201X`](../2201x/), [`22012`](../22012/)

## Sources {#sources}
The executor NULL/zero/negative handling is in [`src/backend/executor/nodeLimit.c#L347-405`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeLimit.c#L347), and the literal `WITH TIES` NULL guard is in [`src/backend/parser/parse_clause.c#L1890-1907`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_clause.c#L1890). The structured [evidence record](../data/evidence/2201w.json) retains both primary roles; no natural runtime was run.
