Skip to content

Error Codes

Every { "type": "error", … } expectation in a conformance fixture may carry an errorCode — a KP-XXXX string that names which specific failure the conforming implementation must raise. errorCode is normative output: a runner must fail with the named code. How the failure materializes is unconstrained (a Kotlin exception hierarchy, a Rust Result/enum, a TypeScript tagged error, etc.). When errorCode is absent or null, the fixture accepts any failure.

The table below is also published as machine-readable data at conformance/error-codes.json (schema: conformance/error-codes.schema.json), so a porter can generate an error enum or validate fixtures against known codes without scraping this page or running any Kotlin. It ships in the same distribution ZIP as the fixtures. A unit test in kpointer-conformance asserts the registry contains exactly the set of errorCode values used across syntax/* and algorithm/* — no more, no fewer — so a typo'd code in a fixture, or a stale entry in the registry, fails the build instead of passing schema validation silently.

Error code table

Code Layer Normative? Meaning
KP-1001 parse RFC 6901 string did not start with /
KP-1002 parse Fragment string did not start with #
KP-1003 parse Truncated or invalid %XX in a fragment
KP-1004 parse ⚠️ advisory JavaScript access path syntactically malformed; requires the jsPath capability — see Capabilities
KP-1005 parse ~ not immediately followed by 0 or 1 (including a trailing ~) — an invalid RFC 6901 escape sequence
KP-2001 relative Relative pointer syntactically malformed (empty, no leading digit, leading zero, bad adjustment, trailing junk)
KP-2002 relative Requested more levels up than the base depth
KP-2003 relative Index adjustment applied at the root
KP-2004 relative Index adjustment on a non-integer segment
KP-2005 relative Index adjustment produced a negative index
KP-2006 relative # used when the resolved pointer is root
KP-3001 resolve Navigated through a primitive intermediate value
KP-3002 resolve Segment addressing a list does not match the RFC 6902 array-index grammar (non-digit, non-ASCII digit, leading zero, or a leading sign)
KP-4001 mutate Set or remove targeted the root pointer
KP-4002 mutate Removed a struct key that is not present
KP-4003 mutate Navigated into an absent or primitive intermediate
KP-4004 mutate List index does not match the RFC 6902 array-index grammar, or is out of range
KP-4005 mutate - used at an intermediate position or for removal

Numeric overflow is deliberately unspecified

The relative-pointer draft declares no maximum for the levels-up prefix or the +N/-N adjustment, so overflow is port-specific: no error code, no fixture. A port may choose its own behavior for arbitrarily large numbers.

Layers

Codes are grouped by the layer of the pointer stack where the failure occurs:

  • parse (KP-1xxx) — raised while parsing a pointer string (RFC 6901, fragment, or JavaScript access path).
  • relative (KP-2xxx) — raised while applying a relative pointer to an absolute base.
  • resolve (KP-3xxx) — raised while resolving an absolute pointer against a document.
  • mutate (KP-4xxx) — raised while applying a set or remove mutation to a document.

How to map codes to your error type

A port does not need to use these strings internally. The codes exist only at the conformance-fixture boundary. The typical pattern is:

  1. Maintain your own exception hierarchy or error enum, with names meaningful to your language.
  2. Write a thin translation function (like canonicalErrorCode() in the Kotlin reference) that maps each internal type to its KP-XXXX string.
  3. In your test runner, call that function on the actual error and compare it to the fixture's errorCode field.

When errorCode is null, skip the comparison and accept any failure. Advisory codes such as KP-1004 are handled through the Capabilities mechanism: when a runner does not declare the jsPath capability, cases that require it are skipped entirely rather than run with a relaxed assertion.