Skip to content

fix(provider): drop empty content messages after interleaved reasoning filter#17712

Closed
jpvelasco wants to merge 4 commits into
anomalyco:devfrom
jpvelasco:fix/interleaved-empty-content-safety-net
Closed

fix(provider): drop empty content messages after interleaved reasoning filter#17712
jpvelasco wants to merge 4 commits into
anomalyco:devfrom
jpvelasco:fix/interleaved-empty-content-safety-net

Conversation

@jpvelasco
Copy link
Copy Markdown

Issue for this PR

Fixes #17705

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The interleaved reasoning filter in normalizeMessages() strips reasoning parts from assistant messages and moves them to providerOptions. When an assistant message contains only reasoning parts (no text, no tool-call), this leaves content: [], which Bedrock's ConverseAPI rejects with a validation error. The session is permanently broken after this.

The empty content guard at lines 54-72 cannot catch this because it runs before the interleaved filter.

The fix adds a check after filtering reasoning parts: if filteredContent is empty, the message is dropped. This follows the same pattern used by the existing empty content guard at line 68.

How did you verify your code works?

  • 6 new unit tests covering reasoning-only messages (single/multiple parts, bedrock, openai-compatible, mixed content, non-interleaved models)
  • 115 existing transform tests pass with 0 regressions
  • Typecheck passes (bun turbo typecheck --filter=opencode)
  • Live tested on Bedrock with amazon-bedrock/zai.glm-4.7 (the only Bedrock model currently with interleaved: { field: "reasoning_content" }). Before the fix: crashes at step 14 with validation error. After the fix: completed 199 steps with 0 errors.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on my searches, I found one potentially related PR:

Related PR:

The other PRs found (like #16750 and #14637) deal with related normalizeMessages and interleaved reasoning concerns, but they appear to address different specific issues rather than duplicates.

Note: PR #17712 is the current PR you're checking, so it's not listed as a duplicate of itself.

@robinmordasiewicz
Copy link
Copy Markdown

We independently hit this bug in a fork while using an openai-compatible provider routing to Anthropic models. Reasoning-only assistant messages became content: [] after the interleaved filter stripped them, causing validation errors downstream.

We arrived at the same fix — if (filteredContent.length === 0) return undefined plus a .filter() on the outer .map(). Tested against an openai-compatible provider with interleaved: { field: "reasoning_content" } and confirmed the crash is gone.

Clean, minimal fix. Would be great to see this merged.

jpvelasco and others added 4 commits April 17, 2026 22:02
…g filter

The interleaved reasoning filter strips reasoning parts from assistant
messages and moves them to providerOptions. When an assistant message
contains only reasoning parts, this leaves content: [], which Bedrock's
ConverseAPI rejects with a validation error. The session is permanently
broken after this.

Fixes anomalyco#17705
@jpvelasco jpvelasco force-pushed the fix/interleaved-empty-content-safety-net branch from a77d875 to 256507f Compare April 18, 2026 05:02
@jpvelasco
Copy link
Copy Markdown
Author

Bumping this with some context to help prioritize:

This PR follows the same pattern as #14586 (merged), which fixed empty content crashes for Bedrock by filtering empty strings. That fix closed #11210. This PR closes the gap for a second code path (the interleaved reasoning filter) which can also produce content: [] on Bedrock, but runs after the existing guard so it was never caught.

Evidence it's a real pain point:

The fix is 2 lines. PR is rebased to current dev, all 6 new tests pass, 0 regressions across the existing transform suite.

@rekram1-node
Copy link
Copy Markdown
Collaborator

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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.

bug(provider): interleaved reasoning filter produces empty content arrays, crashing Bedrock sessions

3 participants