From efb792ff243fedba996eacbafae859a037e69841 Mon Sep 17 00:00:00 2001 From: axelray-dev <110029405+axelray-dev@users.noreply.github.com> Date: Fri, 26 Jun 2026 03:43:05 +0800 Subject: [PATCH] fix: validate content block type in Anthropic assistant blocks (#4060) _assistant_blocks appends dict items from content lists directly without checking for the required 'type' field. A block like {'text': 'hi'} reaches the Anthropic payload without a 'type', causing a 400 rejection. Add the same missing-type check that _convert_user_content already has, so bare dicts in assistant content lists are coerced to text blocks instead of triggering API validation errors. Co-authored-by: nanobot-issues --- nanobot/providers/anthropic_provider.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nanobot/providers/anthropic_provider.py b/nanobot/providers/anthropic_provider.py index 01c5c30c..c52600f6 100644 --- a/nanobot/providers/anthropic_provider.py +++ b/nanobot/providers/anthropic_provider.py @@ -275,7 +275,16 @@ class AnthropicProvider(LLMProvider): blocks.append({"type": "text", "text": content}) elif isinstance(content, list): for item in content: - blocks.append(item if isinstance(item, dict) else {"type": "text", "text": str(item)}) + if isinstance(item, dict): + if not item.get("type"): + # Anthropic requires every content block to declare a "type". + # A tool that returned a bare dict lands here; coerce it to + # a text block instead of emitting one that the API rejects. + blocks.append({"type": "text", "text": str(item)}) + else: + blocks.append(item) + else: + blocks.append({"type": "text", "text": str(item)}) for tc in msg.get("tool_calls") or []: if not isinstance(tc, dict):