Claude Code API 400 after a tool returned an object: Sume results
Claude Code 2.1.286 fixed API 400s when a tool returned an object, number or boolean. Sume tools return text content blocks, errors too.

Update Claude Code to 2.1.286 or later. Its changelog lists a fix for API 400 errors after a tool or hook returned an object, number or boolean instead of text. Sume's hosted MCP tools were not the trigger: the server wraps every result, success or error, in a text content block.
The Claude Code line is from its changelog, read 2026-10-01. The Sume side is from the MCP server source and the MCP tools and gates page.
What did Claude Code change in 2.1.286?
The entry says the 400s followed a tool or hook returning a non-text value, and that the fix covers resumed sessions too. A hook you wrote yourself that prints a bare number is the likelier source than an MCP server.
What shape does a Sume tool result have?
In packages/mcp-server/src/mcp-tool-results.ts, toolResult serializes the redacted payload with JSON.stringify and returns { content: [{ type: "text", text }], isError: false }. The client sees one text block holding JSON, never a raw object. Failures go through toolErrorResult, which returns the same block type with isError: true.
| Case | Content type | isError |
|---|---|---|
| Successful tool call | text (JSON string) | false |
| Tool execution failure | text (JSON string) | true |
| Output over the budget | text with code mcp_output_too_large | true |
What happens when a result is too large?
The output budget is MCP_OUTPUT_MAX_BYTES = 256 * 1024. Past it, the server returns a coded mcp_output_too_large error whose message says it is an output limit, not a job failure, and never to resubmit a paid create. Re-read with a narrower call instead; see job timeouts.
If I still see a 400, what should I check?
Check your own hooks and any other MCP servers first, and confirm claude --version is at least 2.1.286. To see what Sume returned, call tools_list or mcp_health and read the single text block. If the text parses as JSON with a code field, the failure is a Sume error, not a malformed result.
Sources
Related posts
More in Developers
- Claude Code background Bash 30-minute limit and Sume jobs
Claude Code 2.1.285 stops background Bash after 30 minutes by default (2 h max). A Sume render is a job id, so poll it with jobs_wait slices, never resubmit.
- Claude Code Bedrock/Vertex MCP 2026-07-28 default vs Sume
Claude Code on Bedrock, Vertex and Foundry now negotiates MCP 2026-07-28 by default. The opt-out env vars, and the versions the Sume server accepts.
- Claude Code headless MCP auth reminder: Sume key vs OAuth expiry
Claude Code 2.1.286 fixed a repeated MCP auth reminder in headless runs. Sume OAuth tokens last one hour with no refresh, so unattended runs should use a key.
- Claude Code MCP OAuth token lost, keychain locked: Sume tokens
Claude Code 2.1.281 stops a locked macOS keychain from dropping stored MCP OAuth tokens. A Sume token lasts one hour with no refresh grant.
Written by Sume