Skip to content

fix(schema): unescape ~1/~0 in JSON Pointer $ref fragments - #2984

Open
schani wants to merge 6 commits into
masterfrom
agent/fix-issue-2591
Open

fix(schema): unescape ~1/~0 in JSON Pointer $ref fragments#2984
schani wants to merge 6 commits into
masterfrom
agent/fix-issue-2591

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Bug

JSON Schema $ref fragments containing RFC 6901 JSON Pointer escapes (~1 for /, ~0 for ~) were not being unescaped when quicktype split the fragment on / to resolve the referenced path. As a result, a schema with a $defs/definitions key literally named m/z, referenced via "$ref": "#/$defs/m~1z", failed to resolve:

node dist/index.js --lang typescript --src-lang schema schema.json
Error: Key m~1z not in schema object at schema.json#m~1z.

This is a real-world issue — e.g. the Allotrope ASM schemas linked in #2591 use m/z as a property name.

Root cause

Ref.parsePath in packages/quicktype-core/src/input/JSONSchemaInput.ts split ref-fragment path segments on / without unescaping ~1/~0 per RFC 6901. A second split site in nameFromURI had the same gap. Serializing a Ref back to a pointer string (Ref.toString) also didn't re-escape //~ in path segments, so round-tripping a ref would have produced an incorrect pointer.

Fix

Added unescapeJSONPointerSegment (~1/, then ~0~) and escapeJSONPointerSegment (~~0, then /~1) helpers, and applied them at all three sites:

  • Ref.parsePath — unescape each path segment after splitting on /.
  • nameFromURI — same unescaping when deriving a type name from a URI fragment.
  • Ref.toString — escape each path segment when serializing back into a JSON Pointer, so parse/stringify round-trips correctly.

Test coverage

Added a JSON Schema fixture:

  • test/inputs/schema/json-pointer-escaped-keys.schema — a schema with $refs using ~1 and ~0 escapes pointing at definitions keys literally named m/z and a~b.
  • test/inputs/schema/json-pointer-escaped-keys.1.json — a matching sample.

This fixture is picked up automatically by every language's schema fixture (via testsInDir in test/fixtures.ts), so no registration changes were needed.

Verification

  • Confirmed the new fixture fails on unfixed code: Error: Key m~1z not in schema object at .../json-pointer-escaped-keys.schema#m~1z.
  • With the fix, FIXTURE=schema-typescript script/test test/inputs/schema/json-pointer-escaped-keys.schema passes.
  • Re-ran the original issue repro (node dist/index.js --lang typescript --src-lang schema schema.json) and confirmed it now generates correct TypeScript (mz: Mz object with numeric value, tilde: string) instead of erroring.
  • npm run build passes.
  • Other quicktype-supported languages' schema fixtures are left to CI.

Fixes #2591

🤖 Generated with Claude Code

schani and others added 6 commits July 20, 2026 17:02
Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…equired-properties limitation (#2591)

The cjson generator does not implement required-property-absence checking
(same pre-existing, documented limitation as intersection.schema and
required.schema), so its .fail.no-defaults.json case for this schema
never actually fails. Skip it in CJSONLanguage.skipSchema like the other
two schemas with the same limitation; the fix itself is already covered
by every other schema-* fixture.

Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
Brings in master's fix preserving JSON Schema enum source order, which
resolves the cjson-enum-default unit-test failure the stale branch was
producing (alphabetical vs source ordering).

Co-Authored-By: Claude <noreply@anthropic.com>
Resolve the cJSON schema-skip conflict by retaining both master's default-value fixture skip and this PR's JSON Pointer fixture skip.
@github-actions

Copy link
Copy Markdown

Generated-output differences

34 files differ — 0 modified, 34 new, 0 deleted
2505 changed lines — +2505 / −0

Open the generated-output report →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Escaped slashes in keys are not understood

2 participants