Skip to content

fix: filter empty/whitespace text content blocks at provider boundaries#11877

Open
RomneyDa wants to merge 1 commit intomainfrom
fix/empty-text-content-blocks
Open

fix: filter empty/whitespace text content blocks at provider boundaries#11877
RomneyDa wants to merge 1 commit intomainfrom
fix/empty-text-content-blocks

Conversation

@RomneyDa
Copy link
Collaborator

@RomneyDa RomneyDa commented Mar 26, 2026

Summary

Skip empty and whitespace-only text content blocks at each provider's message conversion layer, preventing 400 errors from Anthropic and Bedrock.

3 targeted changes, +14/-5 lines, zero upstream behavioral changes.

Changes

File Change Issues fixed
core/llm/llms/Anthropic.ts .trim() check in convertMessageContentToBlocks #11446
core/llm/llms/Bedrock.ts Skip empty text in _convertMessageContentToBlocks #9765, #9767, #11264, #11497
packages/openai-adapters/src/apis/Bedrock.ts Skip empty text in user message conversion #10148, #10804, #11045

What this does NOT change

  • No upstream message filtering or compilation logic
  • No changes to messages.ts, countTokens.ts, or toResponsesInput
  • Existing " " fallbacks for string content are untouched
  • No changes to the OpenAI adapter's toChatMessage conversion

Issues fixed

Fixes #9765, fixes #9767, fixes #10148, fixes #10804, fixes #11045, fixes #11264, fixes #11446, fixes #11497

Test plan

  • openaiTypeConverters.test.ts — 24/24 pass
  • Prettier clean
  • Manual: Bedrock ConverseStream
  • Manual: Bedrock InvokeModelWithResponseStream
  • Manual: Anthropic direct

@RomneyDa RomneyDa requested a review from a team as a code owner March 26, 2026 06:05
@RomneyDa RomneyDa requested review from Patrick-Erichsen and removed request for a team March 26, 2026 06:05
@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Mar 26, 2026
@RomneyDa
Copy link
Collaborator Author

Why targeted provider-level fixes instead of upstream changes

We initially explored a broader approach (see #11808) that modified the shared message filtering/compilation layer (messages.ts, countTokens.ts) — replacing addSpaceToAnyEmptyMessages with stripEmptyContentParts, fixing chatMessageIsEmpty to handle array content, and changing fallback behavior in toResponsesInput.

We opted against that because:

  • Changing content: null or content: "" for assistant messages could break OpenAI-compatible providers (LM Studio, Ollama, vLLM, etc.) that expect non-null content
  • Removing the " " fallback in addSpaceToAnyEmptyMessages changes behavior for every provider, not just the ones with reported bugs
  • Modifying toResponsesInput to drop empty assistant messages could break Responses API ID chains
  • Silencing the Bedrock empty-turn error would mask bugs instead of surfacing them

Instead, this PR adds .trim() guards at the 4 exact locations where text content blocks are constructed for providers that reject empty/whitespace text. Each fix is a one-liner that only affects the provider with the reported bug.

@continue
Copy link
Contributor

continue bot commented Mar 26, 2026

Documentation Review

No documentation updates are needed for this PR.

Reasoning:

  • This is an internal bug fix to provider message conversion logic that filters empty/whitespace text content blocks before they reach provider APIs
  • The changes are entirely within internal implementation details (convertMessageContentToBlocks, _convertMessageContentToBlocks, toChatMessage) that users never interact with
  • No new user-facing features, configuration options, or behavior changes are introduced
  • The fix resolves 400 errors that were implementation artifacts, not something users could troubleshoot via configuration

The existing documentation for Anthropic and Bedrock providers remains accurate and complete.

@continue
Copy link
Contributor

continue bot commented Mar 26, 2026

Test Coverage Review

This PR introduces a bug fix to filter out empty/whitespace-only text content blocks across multiple provider implementations. Per testing guidelines, bug fixes should include regression tests.

Missing Test Coverage

1. core/llm/openaiTypeConverters.test.ts

The toChatMessage function was modified but has no direct test coverage. Consider adding tests for:

  • Assistant message with content: [{type: 'text', text: ' '}] (whitespace only) should filter out the text part
  • Assistant message with content: [{type: 'text', text: ''}] (empty) should filter out the text part
  • Mixed content with empty/whitespace text parts alongside valid parts should only keep valid parts

2. core/llm/llms/Anthropic.vitest.ts

The content block conversion was modified. Consider adding tests for:

  • Empty string content produces no text blocks
  • Whitespace-only string content produces no text blocks
  • Array content with whitespace-only text parts filters them out

3. core/llm/llms/Bedrock.test.ts

The content conversion was modified. Consider adding to the message conversion describe block:

  • Empty string content produces empty content array
  • Whitespace-only string content produces empty content array
  • Array content with whitespace-only text parts filters them out

4. packages/openai-adapters/src/apis/Bedrock.ts

No test file exists for this module. Consider adding tests for the message conversion helper.

Why These Tests Matter

The bug being fixed (providers rejecting empty/whitespace text blocks) could regress if:

  • Future refactors accidentally remove the .trim() checks
  • Similar functions are added without the same safeguards

Simple unit tests for each affected function would catch these regressions.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 4 files

Skip empty and whitespace-only text content blocks at each provider's
message conversion layer, preventing 400 errors from Anthropic, Bedrock,
Venice, and other OpenAI-compatible APIs.

- Anthropic: check .trim() instead of truthiness in convertMessageContentToBlocks
- Bedrock (core): skip empty text in _convertMessageContentToBlocks
- Bedrock (adapter): skip empty text parts in user message conversion
- OpenAI adapter: filter empty text parts from assistant array content

Fixes #9232, #9765, #9767, #10148, #10293, #10504, #10804, #11045,
#11264, #11446, #11497, #11728
@RomneyDa RomneyDa force-pushed the fix/empty-text-content-blocks branch from f5ccba2 to 64b65a2 Compare March 26, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: Todo

1 participant