Anthropic 400 `all content must be type text if is_error is true` after a parallel `handoff` + tool call (suspected: `tool_reference` content combined with `is_error`)
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- go
- Lĩnh vực
- backend-api-design
Hướng nghiên cứu
Read pkg/model/provider/anthropic/beta_converter.go, especially convertBetaToolResultBlockWithDeferred, and trace how pkg/runtime/loop.go:918 sets the deferral load point. First add a regression test for a parallel tool batch where the deferred result has IsError set; the issue reports this scenario as suspected and unverified. Done means confirming the failing conversion path and ensuring the resulting request is accepted by the Anthropic API.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Version: docker-agent v1.151.0 (the converter code on main is identical), model anthropic/claude-opus-5-5, Beta API with adaptive thinking.
Summary
A session died with a non-retryable 400 on the first model call after a handoff:
error receiving from stream: HTTP 400: invalid_request_error:
messages.66.content.1.tool_result: all content must be type `text` if `is_error` is true
Impact
The whole session becomes unusable. The bad tool_result is part of the conversation history, so every later model call resends it and fails the same way. There is no way to continue or recover in place.
All the work in that session is lost: the context built up over a long multi-agent run, the intermediate results, and the tokens spent producing them. In our case the session was about 100 messages deep, with many tool calls and a long transfer_task result. The failure comes from an unrelated tool that happened to be last in the batch, not from anything the user or agent did wrong, and it gives no warning beforehand. The only remedy is to start a new session from scratch.
Confidence: the log is not conclusive
The debug log does not prove this diagnosis. The log records tool names and output lengths, but not message bodies or is_error flags. What I know and what I'm inferring:
Confirmed from the log
rootissued two parallel tool calls in one turn:handoff(toplanner, 673-char output) andupdate_todos(50-char output).planner's first request had 67 messages and was rejected atmessages.66.content.1, which is the second result in the last user message. By ordering, that is theupdate_todosresult.- The same session earlier had a successful
handoff+create_todospair (2919-char output). - This is the only occurrence in the retained logs, which cover about one day.
Inferred, not confirmed
- That the
update_todosresult hadIsError == true. I never saw its content. The 50-char length and the 400 are consistent with a short error such as an unknown todo id, but a short success message would also be that length. - That the failing block is a
tool_referenceresult. I'm inferring this from the code path below and from the error text. The log does not show which branch of the converter ran. - That the
update_todoscall id was the deferral load point. It is only the expected value givenlastToolCallID(messages).
Not done
- I have not reproduced this in isolation or in a test.
If a maintainer can confirm which branch of convertBetaToolResultBlockWithDeferred produced content.1, or has a debug flag that dumps the outgoing request, that would settle it.
Suspected root cause (from reading the code)
plannerexposes tools that weren't in the session's initial tool set.DeferralTracker.MarkAt(pkg/tools/deferrals.go) marks themDeferred, withDeferredAtToolCallIDset to the id passed in atpkg/runtime/loop.go:918:r.toolDeferrals.MarkAt(sess.ID, lastToolCallID(messages), agentTools). That id is the last tool message in the history, which here would be theupdate_todoscall that ran alongside the handoff.- In
convertBetaToolResultBlockWithDeferred(pkg/model/provider/anthropic/beta_converter.go), a result whose call id has deferred names becomes atool_resultwhose content istool_referenceblocks, withIsErrorcopied from the message:return anthropic.BetaContentBlockParamUnion{OfToolResult: &anthropic.BetaToolResultBlockParam{ ToolUseID: msg.ToolCallID, IsError: param.NewOpt(msg.IsError), Content: content, // tool_reference blocks }}, nil - If that call's result is an error, the request has
is_error: truewith non-text content, which the API rejects with exactly this message.
If the diagnosis is right, whether a session dies depends on whether an unrelated tool that happened to be last in the batch succeeded.
Suggested fix (if the diagnosis holds)
Any of these would work:
- In
convertBetaToolResultBlockWithDeferred, skip thetool_referencebranch whenmsg.IsErroris true and emit the normal text result. - In the runtime, attach the load point to the last non-error tool call, or to the
handoffcall itself, rather than blindly tolastToolCallID. - Add a regression test for a parallel tool batch where the last result has
IsError: trueandDeferredAtToolCallIDpoints at it.
Because the failure is unrecoverable, a defensive sanitize step before sending would also help. It would downgrade any is_error result with non-text content to a plain text result instead of failing the whole session.
Suspected repro (untested)
- Multi-agent config where
roothas ahandofftoplanner, andplannerhas tools thatrootdoesn't, so they're deferred after the handoff. - Have
rootemithandoffand a tool that returns an error (for exampleupdate_todoswith an unknown id) in the same assistant turn, with the failing tool last. planner's first request should return the 400.
- Ngôn ngữ chính
- Go
- Star
- 4.6k
- Fork
- 522
- Merge trung bình
- 8 giờ 43 phút
- Pull request đã merge (30 ngày)
- 239
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của docker/docker-agent
-
Error when trying to run sandbox example?Có thể đã có người làm @dgageot đã nhận hôm nay. Đang mởarea/cli
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
docker/docker-agent#4672 · 1 bình luận · 1 reaction · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
pkg/hooks tests fail with a misleading assertion when jq is not installedCó thể đã có người làm @dwin-gharibi đã nhận 58 ngày trước. Đang mởarea/testing
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
docker/docker-agent#4052 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`remove_directory` and `create_directory` hide work they already did when a later path failsCó thể đã có người làm @dwin-gharibi đã nhận 76 ngày trước. Đang mởarea/tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
docker/docker-agent#3933 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`edit_file` silently edits the first match when `oldText` occurs more than onceCó thể đã có người làm @dwin-gharibi đã nhận 76 ngày trước. Đang mởarea/tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
docker/docker-agent#3929 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Flaky test] TestA2AServer_MultipleRequestsCó thể đã có người làm @aheritier đã nhận hôm nay. Đang mởarea/a2a area/testing flaky-test
docker/docker-agent#4687 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của docker/docker-agent
Issue tương tự
-
OCIRepository: pick the Helm chart layer automatically when the first layer is a provenance fileĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
fluxcd/source-controller#2198 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
webhook: mutating admission silently allows objects when createPatch fails (error discarded)Có thể đã có người làm @lemonzoey đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
volcano-sh/volcano#6138 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG] steve: Updating a resource through /v1 ignores dryRun, fieldManager and fieldValidationĐang mởarea/frameworks area/steve kind/bug team/frameworks
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày