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:
- Maintain your own exception hierarchy or error enum, with names meaningful to your language.
- Write a thin translation function (like
canonicalErrorCode()in the Kotlin reference) that maps each internal type to itsKP-XXXXstring. - In your test runner, call that function on the actual error and compare it to the fixture's
errorCodefield.
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.