Skip to content

fix: crash on non-text content blocks in Anthropic LLM#681

Open
Giggitycountless wants to merge 1 commit into
lastmile-ai:mainfrom
Giggitycountless:fix/anthropic-non-text-block-crash
Open

fix: crash on non-text content blocks in Anthropic LLM#681
Giggitycountless wants to merge 1 commit into
lastmile-ai:mainfrom
Giggitycountless:fix/anthropic-non-text-block-crash

Conversation

@Giggitycountless

@Giggitycountless Giggitycountless commented May 1, 2026

Copy link
Copy Markdown

What changed

Fix 4 crash sites in augmented_llm_anthropic.py where block.text is accessed unconditionally on non-text content blocks (ThinkingBlock, RedactedThinkingBlock, ToolUseBlock).

Bug

The Anthropic API returns Message.content as a union of TextBlock | ToolUseBlock | ThinkingBlock | RedactedThinkingBlock. Only TextBlock has a .text attribute. Three functions accessed .text unconditionally:

Function Line Error
message_param_str 915 AttributeError: dict has no attribute text
message_str 932 AttributeError: ThinkingBlock has no attribute text
anthropic_content_to_mcp_content 1378 AttributeError: ToolUseBlock has no attribute text
anthropic_content_to_mcp_content 1381 KeyError: text

This crashes whenever extended thinking or tool use is active in the response.

Fix

  • message_param_str and message_str: Add hasattr(block, "text") guard before accessing .text
  • anthropic_content_to_mcp_content: Use getattr(block, "text", None) for pydantic models and block.get("text") for dicts

4 lines changed total.

Tests

10 new test cases covering all 4 crash sites:

  • TextBlock (baseline, should work)
  • ToolUseBlock (pydantic model, no .text)
  • ThinkingBlock (pydantic model, no .text)
  • RedactedThinkingBlock (pydantic model, no .text)
  • Mixed blocks (text + tool_use + thinking + redacted)
  • Dict-style tool_use (no "text" key)
  • Dict-style thinking (no "text" key)
  • message_str with ThinkingBlock
  • message_str with ToolUseBlock
  • message_param_str with non-text dict blocks

All 36 tests pass (26 existing + 10 new). Zero regressions.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced stability when processing content blocks with missing or non-standard attributes, preventing crashes in edge cases.
    • Improved error handling for message formatting with unexpected content types.
  • Tests

    • Added test coverage for edge cases involving various content block types and missing expected attributes.

Three functions accessed block.text unconditionally, crashing with
AttributeError (pydantic models) or KeyError (dicts) when encountering
non-text blocks like ThinkingBlock, RedactedThinkingBlock, or ToolUseBlock.

Fixes:
- message_param_str (line 915): hasattr(block, 'text') guard
- message_str (line 932): hasattr(block, 'text') guard
- anthropic_content_to_mcp_content (lines 1378, 1381):
  getattr(block, 'text', None) and block.get('text')

Non-text blocks (ToolUseBlock, ThinkingBlock, RedactedThinkingBlock) do
not have a .text attribute. The existing code assumed all blocks are
TextBlock, causing crashes when extended thinking or tool use is active.

Tests: 10 new test cases covering all 4 crash sites with TextBlock,
ToolUseBlock, ThinkingBlock, RedactedThinkingBlock, mixed blocks, and
dict-style blocks. All 36 tests pass (26 existing + 10 new).
@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd155cf9-54b3-40b4-9aaa-2d06ca0868d9

📥 Commits

Reviewing files that changed from the base of the PR and between f62d849 and b7567d4.

📒 Files selected for processing (2)
  • src/mcp_agent/workflows/llm/augmented_llm_anthropic.py
  • tests/workflows/llm/test_augmented_llm_anthropic.py

📝 Walkthrough

Walkthrough

This change hardens the Anthropic-to-MCP message conversion logic to safely handle content blocks that may lack a .text attribute or be non-dict objects. Safe attribute extraction replaces required access patterns, with fallback to None or direct stringification when text is unavailable.

Changes

Cohort / File(s) Summary
Message Safety Hardening
src/mcp_agent/workflows/llm/augmented_llm_anthropic.py
Updated message_param_str, message_str, and anthropic_content_to_mcp_content to use safe attribute/key access (getattr(), .get()) instead of required access patterns when extracting block text, preventing errors on non-text block types.
Test Coverage for Non-Text Blocks
tests/workflows/llm/test_augmented_llm_anthropic.py
Added comprehensive test suite validating that anthropic_content_to_mcp_content, AnthropicAugmentedLLM.message_str, and message_param_str handle non-text Anthropic content blocks (thinking, redacted_thinking, tool_use) without raising attribute or key errors.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • saqadri

Poem

🐰 A rabbit hops through blocks with care,
Safe attributes everywhere!
No crashes when .text is gone,
Your code stands firm and carries on! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing crashes when handling non-text content blocks in Anthropic LLM integration.
Docstring Coverage ✅ Passed Docstring coverage is 92.86% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant