Repository navigation
fix(combo): strip boolean reasoning field for opencode-go providers - #7891
Conversation
There was a problem hiding this comment.
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.
| export function stripBooleanReasoning(body: JsonRecord): JsonRecord { | ||
| if (!("reasoning" in body)) return body; |
There was a problem hiding this comment.
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.
| 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
- Enforce defensive programming by ensuring appropriate null/undefined checks exist before object property accesses or operators like 'in'.
f413033 to
0150b49
Compare
6b2f321 to
0150b49
Compare
|
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.
0150b49 to
ac6b137
Compare
ac6b137 to
3aacbb0
Compare
eadcbea
into
cheaper-inference:release/v3.8.49
|
Merged — thanks @AndrianBalanescu! Stripping the bare boolean |
…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.
…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.
Problem
opencode-go backed providers (ollama-cloud, opencode-go, opencode, opencode-zen) use a Go
ChatCompletionRequeststruct where thereasoningfield is typed asopenai.Reasoning(a structured type, not a bool).When a client sends
reasoning: trueorreasoning: false— which is valid per the OpenAI API for enabling/disabling reasoning — the Go JSON decoder rejects it with: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 booleanreasoningfield from the request body before forwarding to opencode-go backed providers. This mirrors the existing pattern inmimoThinking.tswhere Xiaomi MiMo gets similar reasoning field normalization.reasoning: true/false→ stripped (lets upstream apply default behavior)reasoning: {effort: "high"}→ forwarded as-is (matches Go struct)reasoning: "high"→ forwarded as-isreasoningfield → no changeTesting
13 unit tests covering: provider detection, boolean stripping (true/false), object/string preservation, reference identity, immutability, and field preservation.