fix(openapi): unmarshal HTTP responses from raw JSON text#389
Merged
Conversation
Primitive-typed response payloads (e.g. `type: string`) generate `unmarshal(json: string)` which JSON.parses its argument, but the HTTP client handed unmarshal the already-parsed value from response.json(). That both failed to type-check (Record is not assignable to string) and threw at runtime (JSON.parse on an already-parsed value) whenever an operation response was a primitive. Hand unmarshal the raw JSON text via JSON.stringify(rawData). Object and array models already accept string or object, and unmarshalByStatusCode takes any, so this is uniform across every reply payload kind, while rawData stays the parsed object for the response wrapper. Tests: - New openapi-primitive runtime spec + config generating string/number response operations, plus a primitive-response runtime test proving they unmarshal correctly (fails before the fix with "not valid JSON"). - channels.spec asserts the generated client unmarshals from JSON.stringify(rawData). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ Deploy Preview for the-codegen-project canceled.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
jonaslagoni
approved these changes
Jul 8, 2026
Contributor
|
🎉 This PR is included in version 0.72.8 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.
Why
When an OpenAPI operation's response schema is a primitive (e.g.
type: stringortype: number), the payload generator emitsunmarshal(json: string)whichJSON.parses its argument. But the generated HTTP client handedunmarshalthe already-parsed value fromresponse.json():For primitive responses this both:
Record<any, any>is not assignable tostring(TS2345), andJSON.parseon an already-parsed value (SyntaxError: Unexpected token 'h', "hello world" is not valid JSON).Object/array payloads happened to work because their
unmarshalacceptsstring | object/string | any[].What
Hand
unmarshalthe raw JSON text viaJSON.stringify(rawData):Every unmarshal variant accepts a string — object (
string | object), array (string | any[]), primitive (string), andunmarshalByStatusCode(any) — so this is uniform across all reply payload kinds.rawDatastays the parsed object for the response wrapper'srawDatafield.Tests
openapi-primitiveruntime fixture (test/runtime/openapi-primitive.json+codegen-openapi-primitive.mjs, wired into the runtimegeneratescript) with operations returning a plainstringand a plainnumber.primitive-response.spec.tsdrives the generated client against a server returning primitive bodies and asserts they unmarshal correctly. This fails before the fix (SyntaxError: ... is not valid JSON) and passes after.channels.specasserts the generated client unmarshals fromJSON.stringify(rawData)(and neverunmarshal(rawData)), locking in the generation change.Independent of #387 (auth narrowing) — both touch
client.tsbut in different regions.🤖 Generated with Claude Code