[PR #11590] fix: strip reasoning parts from messages when switching to non-thinking models (#11571) #13852

Closed
opened 2026-02-16 18:18:41 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/11590

State: closed
Merged: No


Summary

Fixed bug where switching from a thinking model to a non-thinking model mid-session caused API errors due to reasoning parts being sent to models that don't support them.

Problem

When switching from a model with extended thinking (e.g., Claude Opus with thinking enabled) to a model without thinking support (e.g., GPT 5.2, Claude Sonnet without thinking) mid-session, an error occurred:

messages.1.content.0.thinking: each thinking block must contain thinking

The root cause was that reasoning parts from the previous model's responses were stored in message history. When switching to a model that doesn't support interleaved reasoning (capabilities.interleaved === false), these parts were still sent to the API, causing validation errors.

Solution

Modified normalizeMessages() in packages/opencode/src/provider/transform.ts to check if the target model supports interleaved reasoning before including reasoning in providerOptions.

Key Changes:

  1. Added support check: Only include reasoning in providerOptions when model.capabilities.interleaved is an object with a field property
  2. Always filter reasoning parts: Reasoning parts are now filtered out from the content array for all models
  3. Conditional reasoning inclusion: Reasoning text is only added to providerOptions.openaiCompatible[field] when the model supports interleaved reasoning

Technical Details

The fix ensures:

  • For models that support interleaved reasoning (e.g., Claude with thinking, Gemini 3): reasoning parts are extracted and placed in the appropriate providerOptions field (reasoning_content or reasoning_details)
  • For models that don't support interleaved reasoning (e.g., GPT 5.2, Claude Sonnet without thinking): reasoning parts are filtered from the content but NOT added to providerOptions, preventing API validation errors

Benefits

  • Seamless model switching between thinking and non-thinking models
  • No breaking changes to existing functionality
  • Proper handling of model capabilities
  • Minimal code change (restructured existing logic)

Testing

  • Code compiles successfully
  • Logic follows existing code patterns
  • No breaking changes to existing message handling

Issue

Resolves #11571 - Error switching from thinking model to non-thinking model mid-session

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/11590 **State:** closed **Merged:** No --- ## Summary Fixed bug where switching from a thinking model to a non-thinking model mid-session caused API errors due to reasoning parts being sent to models that don't support them. ## Problem When switching from a model with extended thinking (e.g., Claude Opus with thinking enabled) to a model without thinking support (e.g., GPT 5.2, Claude Sonnet without thinking) mid-session, an error occurred: ``` messages.1.content.0.thinking: each thinking block must contain thinking ``` The root cause was that `reasoning` parts from the previous model's responses were stored in message history. When switching to a model that doesn't support interleaved reasoning (`capabilities.interleaved === false`), these parts were still sent to the API, causing validation errors. ## Solution Modified `normalizeMessages()` in `packages/opencode/src/provider/transform.ts` to check if the target model supports interleaved reasoning before including reasoning in providerOptions. ### Key Changes: 1. **Added support check**: Only include reasoning in providerOptions when `model.capabilities.interleaved` is an object with a `field` property 2. **Always filter reasoning parts**: Reasoning parts are now filtered out from the content array for all models 3. **Conditional reasoning inclusion**: Reasoning text is only added to `providerOptions.openaiCompatible[field]` when the model supports interleaved reasoning ## Technical Details The fix ensures: - For models that support interleaved reasoning (e.g., Claude with thinking, Gemini 3): reasoning parts are extracted and placed in the appropriate providerOptions field (`reasoning_content` or `reasoning_details`) - For models that don't support interleaved reasoning (e.g., GPT 5.2, Claude Sonnet without thinking): reasoning parts are filtered from the content but NOT added to providerOptions, preventing API validation errors ## Benefits - ✅ Seamless model switching between thinking and non-thinking models - ✅ No breaking changes to existing functionality - ✅ Proper handling of model capabilities - ✅ Minimal code change (restructured existing logic) ## Testing - Code compiles successfully - Logic follows existing code patterns - No breaking changes to existing message handling ## Issue Resolves #11571 - Error switching from thinking model to non-thinking model mid-session
yindo added the pull-request label 2026-02-16 18:18:41 -05:00
yindo closed this issue 2026-02-16 18:18:41 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13852