Skip to content

fix(go): set ResponseIsOptional when response type is Optional/Nullable#16676

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1782304928-fix-go-response-is-optional
Open

fix(go): set ResponseIsOptional when response type is Optional/Nullable#16676
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1782304928-fix-go-response-is-optional

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

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.EOF and the SDK returns:

expected a *teams.CreateMembersTenantsResponseContent response, but the server responded with nothing

Changes Made

The OpenAPI-to-IR converter already correctly handles mixed 200/204 responses by wrapping the response body type in an Optional container. The v1 Go generator detects this via getOptionalOrNullableContainer(typeReference) != nil at sdk.go:3111, but v2 (which generates raw_client.go) had no equivalent check.

  • HttpEndpointGenerator.ts: Added hasOptionalOrNullableResponse() that inspects endpoint.response.body.json.responseBodyType for Optional or Nullable container wrapping. Passes responseIsOptional: true to the Caller when detected.
  • Caller.ts: Added responseIsOptional field to CallArgs interface and emits ResponseIsOptional: true in generated CallParams when set.
  • seed.yml: Added no-content-response fixture to go-sdk seed tests.
  • Seed fixtures updated: no-content-response and exhaustive fixtures regenerated to include ResponseIsOptional: true in affected endpoints.

Generated CallParams before:

&internal.CallParams{
    URL:      endpointURL,
    Method:   http.MethodPost,
    Response: &response,
}

After (for endpoints with Optional/Nullable response type):

&internal.CallParams{
    URL:                endpointURL,
    Method:             http.MethodPost,
    Response:           &response,
    ResponseIsOptional: true,
}

Testing

  • Seed test no-content-response passes with ResponseIsOptional: true in generated contacts/raw_client.go
  • Seed test exhaustive passes — GetAndReturnOptional endpoint correctly gets ResponseIsOptional: true
  • Regression tests pass: plain-text, oauth-client-credentials fixtures unchanged
  • TypeScript compilation passes (pnpm turbo run compile --filter @fern-api/go-sdk)
  • Formatting check passes

Link to Devin session: https://app.devin.ai/sessions/2ec9715faa89458c893d26e94b9043eb


Open in Devin Review

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-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 0 potential issues.

Open in Devin Review

@github-actions

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-06-24T05:18:39Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
go-sdk square 134s (n=5) 283s (n=5) 128s -6s (-4.5%)

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 fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-06-24T05:18:39Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-06-24 13:22 UTC

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.

0 participants