Bug Description
When a tool call returns an empty string, the Anthropic provider passes content: "" directly into the tool_result content block. The Anthropic API rejects this with:
Error: The content field in the Message object at messages.N is empty. Add a ContentBlock object to the content field and try again.
Location
packages/console/app/src/routes/zen/util/provider/anthropic.ts, in the role === "tool" branch:
if ((m as any).role === "tool") {
msgsOut.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: (m as any).tool_call_id,
content: (m as any).content, // ← empty string passes through unchecked
...cc(),
},
],
})
}
Reproduction
Any tool that returns an empty string (e.g. a write-only tool, a command with no stdout, or a tool that errors silently) will trigger this. The error identifies the exact message index (e.g. messages.13), making it look like a history corruption issue rather than a missing guard.
Fix
content: (m as any).content || "(no output)",
Or more robustly, filter/normalize before building the block:
const toolContent = (m as any).content
content: (typeof toolContent === "string" && toolContent.length > 0)
? toolContent
: Array.isArray(toolContent) && toolContent.length > 0
? toolContent
: "(no output)",
Environment
- opencode (console/zen provider path)
- Anthropic API (claude-sonnet-4-6, claude-opus-4-6)
- Triggered while running oc-dcp agent loop against a project with tools that produce no stdout
Bug Description
When a tool call returns an empty string, the Anthropic provider passes
content: ""directly into thetool_resultcontent block. The Anthropic API rejects this with:Location
packages/console/app/src/routes/zen/util/provider/anthropic.ts, in therole === "tool"branch:Reproduction
Any tool that returns an empty string (e.g. a write-only tool, a command with no stdout, or a tool that errors silently) will trigger this. The error identifies the exact message index (e.g.
messages.13), making it look like a history corruption issue rather than a missing guard.Fix
Or more robustly, filter/normalize before building the block:
Environment