Skip to content

fix(combo): strip boolean reasoning field for opencode-go providers - #7891

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.49from
AndrianBalanescu:fix/opencode-go-reasoning-bool
Jul 21, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.49from
AndrianBalanescu:fix/opencode-go-reasoning-bool

Conversation

@AndrianBalanescu

Copy link
Copy Markdown
Contributor

Problem

opencode-go backed providers (ollama-cloud, opencode-go, opencode, opencode-zen) use a Go ChatCompletionRequest struct where the reasoning field is typed as openai.Reasoning (a structured type, not a bool).

When a client sends reasoning: true or reasoning: false — which is valid per the OpenAI API for enabling/disabling reasoning — the Go JSON decoder rejects it with:

400: json: cannot unmarshal bool into Go struct field
ChatCompletionRequest.reasoning of type openai.Reasoning

Evidence

Observed in production with ollama-cloud/glm-5.2 — 3 consecutive 400 errors in a 30-second window, each with the unmarshal error above.

Fix

Add opencodeReasoningSanitizer.ts — strips the boolean reasoning field from the request body before forwarding to opencode-go backed providers. This mirrors the existing pattern in mimoThinking.ts where Xiaomi MiMo gets similar reasoning field normalization.

  • Boolean reasoning: true/false → stripped (lets upstream apply default behavior)
  • Object reasoning: {effort: "high"} → forwarded as-is (matches Go struct)
  • String reasoning: "high" → forwarded as-is
  • No reasoning field → no change

Testing

13 unit tests covering: provider detection, boolean stripping (true/false), object/string preservation, reference identity, immutability, and field preservation.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a sanitizer service (opencodeReasoningSanitizer.ts) and corresponding unit tests to strip boolean reasoning fields from request bodies for opencode-go backed providers, preventing 400 unmarshaling errors on the Go backend. The reviewer suggested adding a defensive check in stripBooleanReasoning to ensure the body parameter is a non-null object before using the in operator, avoiding potential runtime errors.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +41 to +42
export function stripBooleanReasoning(body: JsonRecord): JsonRecord {
if (!("reasoning" in body)) return body;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To prevent potential runtime exceptions (such as TypeError: Cannot use 'in' operator to search for 'reasoning' in null), we should add a defensive check to ensure body is a non-null object before performing the in operator check.

Suggested change
export function stripBooleanReasoning(body: JsonRecord): JsonRecord {
if (!("reasoning" in body)) return body;
export function stripBooleanReasoning(body: JsonRecord): JsonRecord {
if (!body || typeof body !== "object") return body;
if (!("reasoning" in body)) return body;
References
  1. Enforce defensive programming by ensuring appropriate null/undefined checks exist before object property accesses or operators like 'in'.

@AndrianBalanescu
AndrianBalanescu force-pushed the fix/opencode-go-reasoning-bool branch from f413033 to 0150b49 Compare July 20, 2026 16:54
@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.8.49 July 20, 2026 20:21
@AndrianBalanescu
AndrianBalanescu force-pushed the fix/opencode-go-reasoning-bool branch 2 times, most recently from 6b2f321 to 0150b49 Compare July 21, 2026 00:14
@AndrianBalanescu

Copy link
Copy Markdown
Contributor Author

Closing — the reasoning sanitizer logic is already inlined in ComboService on release/v3.8.49, so this extraction approach is no longer needed. The test coverage can be added separately if useful.

opencode-go backed providers (ollama-cloud, opencode-go, opencode,
opencode-zen) use a Go ChatCompletionRequest struct where the reasoning
field is typed as openai.Reasoning (a structured type). When a client
sends reasoning: true or reasoning: false — valid per the OpenAI API —
the Go JSON decoder rejects it with:

  400: json: cannot unmarshal bool into Go struct field
  ChatCompletionRequest.reasoning of type openai.Reasoning

This strips the boolean reasoning field before forwarding to these
providers, allowing the upstream to apply its own default reasoning
behavior. Object/string forms are left untouched.

Observed in production: 3 consecutive 400 errors from ollama-cloud/glm-5.2
in a 30-second window, each with the unmarshal error.
Adds defensive check for null, undefined, and non-object inputs
as suggested in review. Added unit test coverage for these edge cases.
@diegosouzapw
diegosouzapw force-pushed the fix/opencode-go-reasoning-bool branch from 0150b49 to ac6b137 Compare July 21, 2026 00:57
@AndrianBalanescu
AndrianBalanescu force-pushed the fix/opencode-go-reasoning-bool branch from ac6b137 to 3aacbb0 Compare July 21, 2026 00:57
@diegosouzapw
diegosouzapw merged commit eadcbea into cheaper-inference:release/v3.8.49 Jul 21, 2026
15 checks passed
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Merged — thanks @AndrianBalanescu! Stripping the bare boolean reasoning field before forwarding to opencode-go providers is the right fix (their Go struct types it as a structured object). We rebuilt the branch clean on the current tip (it carried old-main auto-sync drift) — applied only your 2 real commits (the sanitizer + guard + test), your code and authorship intact. Real CI green.

@diegosouzapw diegosouzapw mentioned this pull request Jul 23, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…heaper-inference#7891)

* fix(combo): strip boolean reasoning field for opencode-go providers

opencode-go backed providers (ollama-cloud, opencode-go, opencode,
opencode-zen) use a Go ChatCompletionRequest struct where the reasoning
field is typed as openai.Reasoning (a structured type). When a client
sends reasoning: true or reasoning: false — valid per the OpenAI API —
the Go JSON decoder rejects it with:

  400: json: cannot unmarshal bool into Go struct field
  ChatCompletionRequest.reasoning of type openai.Reasoning

This strips the boolean reasoning field before forwarding to these
providers, allowing the upstream to apply its own default reasoning
behavior. Object/string forms are left untouched.

Observed in production: 3 consecutive 400 errors from ollama-cloud/glm-5.2
in a 30-second window, each with the unmarshal error.

* fix(opencode): add null/primitive guard in stripBooleanReasoning

Adds defensive check for null, undefined, and non-object inputs
as suggested in review. Added unit test coverage for these edge cases.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…heaper-inference#7891)

* fix(combo): strip boolean reasoning field for opencode-go providers

opencode-go backed providers (ollama-cloud, opencode-go, opencode,
opencode-zen) use a Go ChatCompletionRequest struct where the reasoning
field is typed as openai.Reasoning (a structured type). When a client
sends reasoning: true or reasoning: false — valid per the OpenAI API —
the Go JSON decoder rejects it with:

  400: json: cannot unmarshal bool into Go struct field
  ChatCompletionRequest.reasoning of type openai.Reasoning

This strips the boolean reasoning field before forwarding to these
providers, allowing the upstream to apply its own default reasoning
behavior. Object/string forms are left untouched.

Observed in production: 3 consecutive 400 errors from ollama-cloud/glm-5.2
in a 30-second window, each with the unmarshal error.

* fix(opencode): add null/primitive guard in stripBooleanReasoning

Adds defensive check for null, undefined, and non-object inputs
as suggested in review. Added unit test coverage for these edge cases.
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.

2 participants