fix(go): set ResponseIsOptional when response type is Optional/Nullable#16676
fix(go): set ResponseIsOptional when response type is Optional/Nullable#16676devin-ai-integration[bot] wants to merge 1 commit into
Conversation
When an endpoint declares both a 200 (with body) and 204 (no body) success response, the OpenAPI-to-IR converter wraps the response body type in an Optional container. The v1 Go generator already detected this via getOptionalOrNullableContainer(), but v2 (which generates raw_client.go) did not check for it. Add hasOptionalOrNullableResponse() to HttpEndpointGenerator which inspects the endpoint's JSON response body TypeReference for Optional or Nullable container wrapping, and passes responseIsOptional: true to the Caller when detected. This causes the generated CallParams to include ResponseIsOptional: true, so caller.go returns a successful nil response on 204 instead of an io.EOF error. Also adds the no-content-response fixture to go-sdk seed tests. Co-Authored-By: rishabh <rishabh@buildwithfern.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
SDK Generation Benchmark ResultsComparing PR branch against median of 5 nightly run(s) on Full benchmark table (click to expand)
main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via |
Description
Fixes a bug where endpoints declaring both a 200 (with body) and 204 (no body) success response would return an error on 204 instead of a successful nil response. When the API returns a real 204, the JSON decoder hits
io.EOFand the SDK returns:Changes Made
The OpenAPI-to-IR converter already correctly handles mixed 200/204 responses by wrapping the response body type in an
Optionalcontainer. The v1 Go generator detects this viagetOptionalOrNullableContainer(typeReference) != nilatsdk.go:3111, but v2 (which generatesraw_client.go) had no equivalent check.HttpEndpointGenerator.ts: AddedhasOptionalOrNullableResponse()that inspectsendpoint.response.body.json.responseBodyTypeforOptionalorNullablecontainer wrapping. PassesresponseIsOptional: trueto the Caller when detected.Caller.ts: AddedresponseIsOptionalfield toCallArgsinterface and emitsResponseIsOptional: truein generatedCallParamswhen set.seed.yml: Addedno-content-responsefixture to go-sdk seed tests.no-content-responseandexhaustivefixtures regenerated to includeResponseIsOptional: truein affected endpoints.Generated
CallParamsbefore:After (for endpoints with Optional/Nullable response type):
Testing
no-content-responsepasses withResponseIsOptional: truein generatedcontacts/raw_client.goexhaustivepasses —GetAndReturnOptionalendpoint correctly getsResponseIsOptional: trueplain-text,oauth-client-credentialsfixtures unchangedpnpm turbo run compile --filter @fern-api/go-sdk)Link to Devin session: https://app.devin.ai/sessions/2ec9715faa89458c893d26e94b9043eb