Skip to content

Fix: Handle empty message content in AnthropicCompletion - Fixes #4427#4479

Open
paipeline wants to merge 1 commit intocrewAIInc:mainfrom
paipeline:fix/empty-message-content-4427
Open

Fix: Handle empty message content in AnthropicCompletion - Fixes #4427#4479
paipeline wants to merge 1 commit intocrewAIInc:mainfrom
paipeline:fix/empty-message-content-4427

Conversation

@paipeline
Copy link
Contributor

@paipeline paipeline commented Feb 13, 2026

Summary

This PR fixes issue #4427 where AnthropicCompletion fails with a BadRequestError when empty user message content is provided.

Problem

The Anthropic API enforces strict validation: all messages must have non-empty content except for an optional final assistant message. When empty content is passed (common in agent output-to-input pipelines), the current implementation forwards it directly to the API, causing predictable 400 errors.

Solution

  • Added _filter_empty_content_messages() method: Filters out messages with empty content while preserving conversation flow
  • Preserves final assistant messages: Allows empty final assistant messages as per Anthropic API rules
  • Handles multiple content types: Correctly identifies empty strings, whitespace-only strings, and empty lists
  • Maintains conversation integrity: Ensures first message is from user and conversation flow is preserved

Changes

  1. lib/crewai/src/crewai/llms/providers/anthropic/completion.py:

    • Added _filter_empty_content_messages() method with comprehensive empty content detection
    • Modified _format_messages_for_anthropic() to apply filtering before returning messages
    • Added safeguards to ensure valid conversation structure after filtering
  2. lib/crewai/tests/llms/anthropic/test_anthropic.py:

    • Added comprehensive test coverage for empty content handling
    • Tests various scenarios: empty strings, whitespace, empty lists, mixed content types
    • Verifies that final assistant messages with empty content are preserved
    • Ensures API calls no longer fail with empty content

Testing

  • ✅ All existing tests pass
  • ✅ New test coverage for empty content scenarios
  • ✅ Verified fix prevents BadRequestError with empty content
  • ✅ Confirmed final empty assistant messages are correctly preserved

Breaking Changes

None. This is a backward-compatible fix that handles edge cases gracefully.

Related Issues

Fixes #4427

Before this fix:

llm = LLM(model="claude-3-haiku-20240307", api_key=os.getenv('ANTHROPIC_API_KEY'))
result = llm.call([{"role": "user", "content": ""}])  # ❌ BadRequestError

After this fix:

llm = LLM(model="claude-3-haiku-20240307", api_key=os.getenv('ANTHROPIC_API_KEY'))
result = llm.call([{"role": "user", "content": ""}])  # ✅ Works (empty content filtered)

Note

Low Risk
Small, localized pre-processing change to outbound Anthropic message payloads with added tests; low risk aside from potential subtle changes in conversation history when empty messages were previously preserved.

Overview
Prevents Anthropic messages.create 400s by filtering out empty/whitespace/empty-list message content during _format_messages_for_anthropic, while still allowing the optional final empty assistant message required by Anthropic.

Adds a dedicated _filter_empty_content_messages helper plus post-filter safeguards to ensure the request still starts with a valid initial user message (falling back to a default "Hello" when needed). Includes a regression test covering the filtering rules and verifying that a call with empty user content sends non-empty messages to the mocked API.

Written by Cursor Bugbot for commit 9160af6. This will update automatically on new commits. Configure here.

…AIInc#4427

- Add _filter_empty_content_messages() method to filter out messages with empty content
- Preserve final assistant messages with empty content (as allowed by Anthropic API)
- Filter out user and non-final assistant messages with empty/whitespace-only content
- Add comprehensive test coverage for empty content handling
- Prevents BadRequestError when empty content is passed in agent pipelines
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

filtered_messages.append({"role": "user", "content": "Hello"})
elif filtered_messages[0]["role"] != "user":
# If first message is not from user after filtering, insert a user message
filtered_messages.insert(0, {"role": "user", "content": "Hello"})
Copy link

Choose a reason for hiding this comment

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

Filtering empty messages breaks required message alternation

Medium Severity

_filter_empty_content_messages can remove messages from the middle of a conversation, creating consecutive same-role messages that violate Anthropic's alternation requirement. For example, [user:"hello", assistant:"", user:"world"] becomes [user:"hello", user:"world"] after filtering. The post-filter validation only checks that the list is non-empty and starts with a user message, but never re-validates alternation. This can produce API errors — the very thing the fix aims to prevent.

Additional Locations (1)

Fix in Cursor Fix in Web

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] AnthropicCompletion fails to handle empty user message content

2 participants