Skip to content

fix: filter empty user message content in AnthropicCompletion#4429

Open
Chase-Xuu wants to merge 3 commits intocrewAIInc:mainfrom
Chase-Xuu:fix/issue-4427-empty-message
Open

fix: filter empty user message content in AnthropicCompletion#4429
Chase-Xuu wants to merge 3 commits intocrewAIInc:mainfrom
Chase-Xuu:fix/issue-4427-empty-message

Conversation

@Chase-Xuu
Copy link

@Chase-Xuu Chase-Xuu commented Feb 9, 2026

Fixes #4427

Summary

The Anthropic API requires all messages to have non-empty content except for the optional final assistant message. When messages with empty string content are passed to the API, it returns a 400 error:

```
messages.0: all messages must have non-empty content except for the optional final assistant message
```

Changes

This PR adds validation in `_format_messages_for_anthropic()` to:

  • Filter out messages with empty or whitespace-only content
  • Allow empty content only for the final assistant message (per API spec)
  • Fall back to a default "Hello" message if all messages are filtered out

Testing

Added regression tests to verify:

  • Empty user messages are filtered
  • Whitespace-only messages are filtered
  • Mixed empty and valid messages are handled correctly
  • Final empty assistant message is preserved (as allowed by API)

Note

Medium Risk
Touches core message pre-processing for all Anthropic calls; filtering and placeholder insertion could subtly change conversation history and tool-call flows, though covered by targeted tests.

Overview
Prevents Anthropic 400s by tightening _format_messages_for_anthropic() validation: drops empty/whitespace-only messages, only permits empty content for the final assistant message, and inserts placeholder turns when filtering would break required role alternation.

Also strips trailing whitespace from the final assistant message (Anthropic rejects it), and adds regression tests covering empty-message filtering, alternation placeholder insertion, and final-assistant whitespace/emptiness edge cases.

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

@Chase-Xuu Chase-Xuu force-pushed the fix/issue-4427-empty-message branch from 029b9d9 to faa89be Compare February 9, 2026 23:33
@Chase-Xuu
Copy link
Author

The Cursor Bugbot concerns have been addressed:

  1. Tests asserting whitespace stripping: The implementation now includes actual .rstrip() logic for trailing whitespace in final assistant messages.

  2. Empty message filtering breaking role alternation: Fixed by implementing role alternation maintenance after filtering - the code now inserts placeholder messages to maintain user/assistant alternation.

Note: This PR is related to #4430 which addresses the same issues from a different angle. You may want to consider merging one after the other to avoid conflicts.

Fixes crewAIInc#4427

The Anthropic API requires all messages to have non-empty content except
for the optional final assistant message. When messages with empty string
content are passed to the API, it returns a 400 error:

  'messages.0: all messages must have non-empty content except for the
   optional final assistant message'

This commit adds validation in _format_messages_for_anthropic() to:
- Filter out messages with empty or whitespace-only content
- Allow empty content only for the final assistant message (per API spec)
- Fall back to a default 'Hello' message if all messages are filtered out

Also adds regression tests to verify the fix.
Address review feedback:
1. Strip trailing whitespace from final assistant message (tests now pass)
2. Maintain role alternation after empty message filtering by inserting placeholders
The role alternation fix inserts placeholder messages when filtering creates
consecutive same-role messages. Updated test to expect 3 messages with the
placeholder assistant message.
@Chase-Xuu Chase-Xuu force-pushed the fix/issue-4427-empty-message branch from faa89be to f86b84d Compare February 13, 2026 16:02
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.

# Insert a placeholder message to maintain alternation
placeholder_role = "assistant" if curr_role == "user" else "user"
fixed_messages.append({"role": placeholder_role, "content": "..."})
fixed_messages.append(message)
Copy link

Choose a reason for hiding this comment

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

Synthetic placeholders alter conversation meaning

Medium Severity

_format_messages_for_anthropic() now injects synthetic {"content": "..."} messages whenever two adjacent roles match. These fabricated user/assistant turns change the actual conversation payload, so the model receives content that never existed in the original chat history.

Fix in Cursor Fix in Web

@Chase-Xuu
Copy link
Author

Thanks for catching this! Good point about the synthetic placeholders altering conversation meaning.

Fixed: Instead of inserting {"content": "..."} placeholders, consecutive same-role messages are now merged together. This:

  • Preserves all original content
  • Maintains Anthropic's role alternation requirement
  • Handles both string and list content formats

Example: Two consecutive user messages "Hello" and "World" become a single "Hello\n\nWorld" message.

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

1 participant