---
title: "Reference: Runtime Error Registry"
description: "Reference for the closed runtime gateway error taxonomy, its surfaces, the invariants and conformance tests that back them, its proof surfaces, and its limits."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/reference/runtime-error-registry/
---

# Reference: Runtime Error Registry

{% version engineVersion="v1.0.232" coordinate="docs-public.v0" /%}

_Last verified 2026-09-03 against engine v1.0.232._

The runtime error registry is the closed, typed taxonomy of runtime gateway failures: one catalog that every runtime failure resolves a stable machine code against, projected to the frontend and to a generated reference, and read at the boundary that turns a thrown error into a player-safe public code. This page is the contract for its **surfaces, invariants, proof surfaces, and limits**. It links down to the generated catalog and never restates it; for the codes themselves, their categories and dispositions, and the static copy each carries, read the generated reference.

{% generated-reference file="docs/spec/generated/error-catalog.md" label="Runtime Error Catalog (generated)" /%}

The model behind this reference (why failures are typed rather than parsed, and which behaviors are the catalog's versus the frontend's) is in the [Runtime Error Registry explanation](../explanation/runtime-error-registry.md).

## Source of truth

The taxonomy is owned in one file and projected, never re-authored:

- **The catalog** `RUNTIME_ERROR_CATALOG` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` is the single source of truth. The code union `RuntimeGatewayErrorCode`, the ordered `RUNTIME_ERROR_CODES`, the closed `RUNTIME_ERROR_CATEGORIES`, and the lookup `runtimeErrorCatalogEntry` all derive from it.
- **The frontend registry** `web_client/spa/src/runtime/generated/runtimeErrorRegistry.gen.ts` is generated from the catalog by `generateRegistrySource` in `scripts/generate-runtime-error-registry.mjs`.
- **The generated reference** `docs/spec/generated/error-catalog.md` is generated from the same catalog by `gen-error-catalog-docs.ts`.
- **The boundary classifier** `runtimeGatewayPublicCode` in `server/src/modules/runtime/routes.ts` maps a thrown error to a stable public code, and `runtimeGatewayPublicMessageForCode` maps that code to player copy from the catalog.

## Surfaces

| Surface | Symbol |
| --- | --- |
| Catalog constant and derived code union | `RUNTIME_ERROR_CATALOG`, `RUNTIME_ERROR_CODES`, `RuntimeGatewayErrorCode` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Entry shape | `RuntimeErrorCatalogEntry` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Closed category tuple | `RUNTIME_ERROR_CATEGORIES` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Engine-contract prefix family | `RUNTIME_ENGINE_CONTRACT_CODE_PREFIX` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Lookups | `runtimeErrorCatalogEntry`, `isRuntimeGatewayErrorCode`, `isRuntimeGatewayCodedError` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Total disposition | `runtimeErrorCategoryDisposition`, `assertNever` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Throw facade | `codedError`, `RuntimeGatewayCodedError` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` |
| Frontend registry generator | `generateRegistrySource`, `writeRegistry`, `checkRegistryDrift`, `OUTPUT_PATH` in `scripts/generate-runtime-error-registry.mjs` |
| Generated frontend registry | `RUNTIME_ERROR_REGISTRY_GEN` in `web_client/spa/src/runtime/generated/runtimeErrorRegistry.gen.ts` |
| Generated-reference generator | `gen-error-catalog-docs.ts` emitting `docs/spec/generated/error-catalog.md` |
| Boundary classifier and copy | `runtimeGatewayPublicCode`, `runtimeGatewayPublicMessageForCode`, `runtimeGatewayPublicMessage` in `server/src/modules/runtime/routes.ts` |
| Frontend presentation | `feCategoryForCode`, `runtimeErrorPresentation` in `web_client/spa/src/runtime/runtimeErrorPresentation.ts` |

## Invariants

Each row is backed by a named conformance test or check.

| Invariant | Proven by |
| --- | --- |
| The committed frontend registry is a byte-exact projection of the catalog (a fresh render equals the committed file), and the generator's own drift check reports no drift. | `server/tests/runtimeErrorTaxonomy.test.ts` (FE registry codegen is in sync); `check:runtime-error-registry` |
| Every catalogued code and the engine-contract prefix are present in the rendered registry. | `server/tests/runtimeErrorTaxonomy.test.ts` (every catalogued code and the engine-contract prefix is present in the rendered registry) |
| No message-regex error classification survives under the runtime module. | `check:runtime-error-taxonomy` part (a), delegated to `scripts/check-no-prose-error-matching.mjs` |
| Every `codedError("literal")` throw site names a catalog code (engine-contract prefix allowed); variable-argument sites are type-checked instead. | `check:runtime-error-taxonomy` part (c), `analyzeCodedErrorSites` in `scripts/check-runtime-error-taxonomy.mjs` |
| The routes boundary is catalog-backed and the hand tables are deleted; player copy routes through `runtimeErrorCatalogEntry`. | `server/tests/runtimeErrorTaxonomy.test.ts` (the boundary is catalog-backed; the legacy public-message table and both hand-tables are deleted) |
| Every code the deleted public table used to ship still has a catalog entry. | `server/tests/runtimeErrorTaxonomy.test.ts` (catalogues every code the deleted public table used to ship) |
| The classifier maps thrown errors to the correct public code: the two internal aliases resolve to `game_full` and `game_updating`, catalog members pass through, and an untyped error maps to `runtime_internal`. | `server/src/modules/runtime/runtimeGatewayErrors.test.ts` (`runtimeGatewayPublicCode` cases) |
| Category and retryability rules hold (auth is terminal except `runtime_credential_expired`; schema_violation is never retryable; revoked is terminal and non-retryable; capacity is terminal-but-retryable; the first-frame family is retryable and non-terminal at the base). | `server/tests/runtimeErrorTaxonomy.test.ts` (category and retryability invariants) |
| The category disposition is total at compile time (`assertNever`) and at runtime. | `server/tests/runtimeErrorTaxonomy.test.ts` (`runtimeErrorCategoryDisposition` is total over the closed category union) |
| `RuntimeGatewayCodedError` populates code/category/retryable/terminal from the catalog, chains the cause, and is narrowable by code. | `server/tests/runtimeErrorTaxonomy.test.ts` (RuntimeGatewayCodedError throw contract) |
| The generated reference is a byte-exact render of the catalog. | `gen-error-catalog-docs.ts --check`, run inside `gen-docs:check` |

## Proof surfaces

- **Frontend drift-sync.** `server/tests/runtimeErrorTaxonomy.test.ts` renders the catalog fresh and asserts byte-equality with the committed `runtimeErrorRegistry.gen.ts`; `checkRegistryDrift` in the generator pins the same equality as a check.
- **Boundary classification.** `server/src/modules/runtime/runtimeGatewayErrors.test.ts` drives `runtimeGatewayPublicCode` and `runtimeGatewayPublicMessage` across the alias, authority-recovering, access-denied, admission, and untyped cases, and asserts no internal prose reaches player copy.
- **Boundary lint.** `check:runtime-error-taxonomy` (in the root `check` chain) delegates no-prose-classification to `scripts/check-no-prose-error-matching.mjs`, runs the generator drift check, and runs `analyzeCodedErrorSites` over `server/src/modules/runtime`; `check:runtime-error-registry` (also in the chain) runs the generator drift check on its own.
- **Generated-reference drift.** `gen-error-catalog-docs.ts --check` inside `gen-docs:check` holds `docs/spec/generated/error-catalog.md` byte-exact against the catalog.

## Numbers

The runtime error code count and category count are carried by the generated reference (its `Error code count` and `Category count` lines) and are not restated here; read them from the generated [Runtime Error Catalog](../../../spec/generated/error-catalog.md). They are pinned by `gen-docs:check` (byte-exact projection) and by the drift-sync and deleted-table-coverage tests in `server/tests/runtimeErrorTaxonomy.test.ts`.

| Value | Symbol | Receipt |
| --- | --- | --- |
| Engine-contract code prefix `runtime_engine_contract_` | `RUNTIME_ENGINE_CONTRACT_CODE_PREFIX` in `server/src/modules/runtime/errors/runtimeErrorCatalog.ts` | `server/tests/runtimeErrorTaxonomy.test.ts` (the engine-contract prefix is present in the rendered registry); `gen-error-catalog-docs.ts --check` |

The `retryable` and `terminal` values are per-entry data, not numeric constants; they are pinned by the category and retryability invariants above rather than by a scalar.

## Limits

- **Terminal-when-disconnected is not catalog data.** The first-frame family is retryable and non-terminal in the catalog; the disconnected-terminal promotion lives in `TERMINAL_WHEN_DISCONNECTED` in `web_client/spa/src/runtime/runtimeErrorPresentation.ts`.
- **The Retry affordance is frontend policy.** `NO_RETRY_ACTION` in `runtimeErrorPresentation.ts` decides whether a Retry label appears; the catalog does not carry it.
- **Two internal codes are not catalog members.** `RUNTIME_CAPACITY_EXHAUSTED_CODE` and `RUNTIME_DEPLOYMENT_SUPERSEDED_CODE` in `server/src/modules/runtime/runtimeGatewayErrors.ts` only alias onto `game_full` and `game_updating` inside `runtimeGatewayPublicCode`.
- **`runtime_origin_forbidden` bypasses the catalog.** It is emitted directly as a 403 with an inline message in `server/src/modules/runtime/routes.ts`, is not a catalog member, does not pass through the classifier or `runtimeGatewayPublicMessageForCode`, and returns nothing from `runtimeErrorPresentation` on the frontend (generic fallback copy). The catalog is the taxonomy the classifier produces, not every code the gateway can emit.
- **The frontend category enum is hand-maintained.** `feCategoryForCode` in `runtimeErrorPresentation.ts` is distinct from the taxonomy category and falls back to a generic connection category for any unmapped taxonomy value, so a newly added taxonomy category is not surfaced there automatically.
- **`runtime_connection_unverified` is a retained catch-all** kept for server-table coverage during migration; new throw sites should use a specific split code (`runtime_auth_invalid`, `runtime_credential_expired`, `runtime_release_stale_link`, or `runtime_session_ended`).
- **Variable-argument `codedError(code)` sites are out of scope for the taxonomy gate** and rely on the TypeScript union check instead of `analyzeCodedErrorSites`.
- **The `runtime_internal` operator description names a stale logger.** The live logger is `logRuntimeGatewayUntypedError` in `server/src/modules/runtime/routes.ts`; the operator string recorded on the `runtime_internal` entry names a different, non-live function and is emitted verbatim into the generated reference. It is operator-facing text only and never reaches a player.
- **The unit is not enrolled in the feature-contract registry.** `server/src/lib/featureContractRegistry.ts` carries no entry for it, so the closure gate does not yet force its anchor to resolve; it sits at the internal tier.

{% warning severity="caution" title="Operator copy is not player copy" %}
The `opsDescription` on each catalog entry is log-facing and can name internal functions, SQLSTATE codes, and deployment states. It is never shown to a player: player screens draw only `playerTitle` and `playerMessage`, which are static and player-safe by construction. Read the operator descriptions from the generated [Runtime Error Catalog](../../../spec/generated/error-catalog.md), and treat them as operator context, not user-facing copy.
{% /warning %}
