Skip to content

fix: filter empty content blocks for Bedrock provider#14586

Open
Tom-Ryder wants to merge 2 commits intoanomalyco:devfrom
Tom-Ryder:fix/bedrock-empty-content
Open

fix: filter empty content blocks for Bedrock provider#14586
Tom-Ryder wants to merge 2 commits intoanomalyco:devfrom
Tom-Ryder:fix/bedrock-empty-content

Conversation

@Tom-Ryder
Copy link

@Tom-Ryder Tom-Ryder commented Feb 21, 2026

Issue for this PR

Closes #11210

Type of change

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

What does this PR do?

normalizeMessages() filters empty text/reasoning parts for @ai-sdk/anthropic but not @ai-sdk/amazon-bedrock. The Bedrock Converse API has the same constraint — empty content arrays cause "content field is empty" and invalid cache point errors that permanently break the session. Extended the existing guard to also cover Bedrock.

Note: this fixes the empty content filtering side of #11210. The separate Bedrock ConverseAPI tool call issues flagged in the thread will need a follow-up.

How did you verify your code works?

  • bun turbo typecheck passes
  • Added 6 tests mirroring the existing anthropic empty content filtering suite, all pass
  • Existing tests unchanged and passing

Screenshots / recordings

N/A — backend logic change.

Checklist

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

@github-actions
Copy link
Contributor

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

Based on my search, I found related PRs but no direct duplicates of PR #14586:

Related PRs:

  1. PR fix(provider): trim whitespace and filter empty content in transformations #7086 - "fix(provider): trim whitespace and filter empty content in transformations"

    • Addresses similar empty content filtering but appears to be from an earlier iteration
  2. PR fix: expand Anthropic detection and strip whitespace-only text blocks #12634 - "fix: expand Anthropic detection and strip whitespace-only text blocks"

    • Related to the anthropic filtering mentioned in your PR description
  3. PR fix: strip incompatible thinking blocks when switching to Claude (improved) #11882 - "fix: strip incompatible thinking blocks when switching to Claude (improved)"

    • Part of the broader content filtering effort for different providers

These are related to content filtering improvements, but none appear to be addressing the exact same issue (filtering empty content blocks for Bedrock specifically with the normalizeMessages() function).

No duplicate PRs found

@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@marcosvrs
Copy link

Tested this exact failure pattern in production usage with Bedrock Claude in OpenCode:\n\nundefined: The content field in the Message object at messages.X is empty\n\nI dug into the transform path and confirmed the root cause aligns with this PR: empty text/reasoning filtering currently runs for @ai-sdk/anthropic but not @ai-sdk/amazon-bedrock, so Bedrock Converse receives empty content arrays and rejects the request.\n\nFor Bedrock-only users, this is a hard blocker because there is no config-level workaround that preserves thinking behavior. Disabling thinking reduces frequency but is not an equivalent fix.\n\nWould appreciate prioritizing merge/release of this patch when possible - it unblocks a significant Bedrock Claude workflow.

Comment on lines +138 to +140
return msgs
.map((msg) => {
if (msg.role === "assistant" && Array.isArray(msg.content)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why change this unrelated stuff?


test("keeps non-text/reasoning parts even if text parts are empty", () => {
test("drops assistant message that has only reasoning parts", () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

hm im not sure if this one is correct

@@ -51,7 +51,7 @@ export namespace ProviderTransform {
): ModelMessage[] {
// Anthropic rejects messages with empty content - filter out empty string messages
// and remove empty text/reasoning parts from array content
if (model.api.npm === "@ai-sdk/anthropic") {
if (model.api.npm === "@ai-sdk/anthropic" || model.api.npm === "@ai-sdk/amazon-bedrock") {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why can't we just have this change +1 test for it, ill cleanup later cause we should be a bit better at doing this across the board but htere was a special case that caused errors in the past

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.

Kimi K2 via AWS BEDROCK stops execution

3 participants