Fix "Type creator didn't return its forwarding ref" crash on sibling maps#2877
Merged
Conversation
UnifyUnionBuilder.makeObject's map branch called getMapType without the pending forwardingRef, while the class/object branches pass it through. When inferMaps rewrites sibling classes that unify into a map (e.g. a map-typed field whose values contain both non-empty and empty maps), the type creator then returned a ref different from its forwarding ref, tripping the "Type creator didn't return its forwarding ref" assert in GraphRewriteBuilder.withForwardingRef and crashing for every target language. Add the minimized JSON from issue #2037 as a priority regression fixture; it crashed before this fix and now converts for all languages. Fixes #2037 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull Bot
pushed a commit
to meonBot/quicktype
that referenced
this pull request
Jul 14, 2026
…ps#2881) Maps of empty objects render as Map<String, X> with typealias X = JsonObject, but Klaxon's reflective deserializer never consults custom converters for map values, so parsing fails with "Couldn't find a suitable constructor for class JsonObject to initialize with {}". Adds unit tests expecting such fields to be handled by a field-level converter, and re-enables the bug2037.json fixture for Kotlin/Klaxon that glideapps#2877 had to skip. The unit tests currently fail; the fix follows in the next commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Valid JSON input with sibling map-typed fields — where one map has entries and a sibling map is empty — crashes quicktype for every target language with:
(The web app swallows the error, so it just silently produces nothing.) Minimal 126-byte repro:
{"mission_specs": {"1": {"objectives": {"2": {"rewards": {"3": {}, "5": {}}}}}, "4": {"objectives": {"6": {"rewards": {}}}}}}The only workaround was
--no-maps.Root cause
In
UnifyClasses.ts,UnifyUnionBuilder.makeObjecthas three branches for combining object types. The class branch (getUniqueClassType) and the object branch (getUniqueObjectType) both pass the pendingforwardingRefthrough, but the map branch calledthis.typeBuilder.getMapType(typeAttributes, ...)without it. When theinferMapsrewrite unifies sibling classes into a map, the newly created map type gets a fresh ref instead of consuming the forwarding ref, tripping the assert inGraphRewriteBuilder.withForwardingRef(GraphRewriting.ts).Fix
One line: pass
forwardingReftogetMapTypein the map branch, matching the other two branches (getMapTypealready accepts an optionalforwardingRefparameter).Tests
Test first: the minimized JSON was added as
test/inputs/json/priority/bug2037.jsonbefore the fix, andFIXTURE=golang script/test test/inputs/json/priority/bug2037.jsonwas run against the unpatched build — it failed with the exact crash (Internal error: Type creator didn't return its forwarding ref, thrown fromGraphRewriteBuilder.withForwardingRefviaUnifyUnionBuilder.makeObject). After the fix, the same run passes (Go generation, compile, and JSON round-trip).Since
priority/inputs run for all languages, this fixture guards the fix everywhere.Verification
QUICKTEST=1 FIXTURE=golang script/test(all 41 priority/schema samples incl. the new one) passes locally — no regressions from the new priority input.sync.txtattachment from the issue, plus all minimized variants from triage, now convert successfully (verified with--lang csharp).priority/.This also fixes the duplicates #1320 and #1509 (same forwarding-ref crash).
Fixes #2037
🤖 Generated with Claude Code