Conversation
Importing an Anthropic Messages dump dropped `is_error` from `tool_result` blocks, and importing a DeerFlow run-event file dropped `status: "error"` from LangChain tool messages. Failed tool calls then showed as successful and were replayed to the model as successful results. Carry the flag through as `output.isError`; successful results are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a conversation is imported (file import or drag-and-drop), failed tool calls come in as successful:
tool_resultblock withis_error: trueloses the flag.ToolMessage.model_dump(), so a failed call carries LangChain'sstatus: "error". That field is ignored too.The imported tool call then shows as completed rather than errored (
getToolCallStatus()readsoutput.isError). Re-running the thread also replays that result to the model withisError: false(convertToPiContext()), so the model is told a failed call succeeded. For a workbench used to debug agents, that hides exactly the failure being investigated.normalizeToThread()already resolves both shapes. The flag was simply not carried to_attachToolResult(). It now setsoutput.isError: truefor failed results. Successful results keep the exact{ content }output they had before, so already-imported or saved threads do not change shape.Validation
bun test packages/core/tests/parsers/json-thread-parser.test.ts packages/core/tests/parsers/deerflow-jsonl-thread-parser.test.tsBefore the fix (new tests added, source unchanged):
json-thread-parser.test.ts: 4 pass, 1 faildeerflow-jsonl-thread-parser.test.ts: 5 pass, 1 failAfter the fix: 11 pass, 0 fail across both files.
toEqual({ content: [...] }), with noisErrorkey) passes both before and after. The existing DeerFlow import test, which pins a successful tool output exactly, is also unchanged. This shows successful results are not rewritten.bun test packages/core/tests/parsers packages/core/tests/thread packages/core/tests/client: 138 pass, 0 fail.--max-warnings 0) on the three touched files: clean onmainand on this branch.tsc --noEmit -p tsconfig.json: clean.normalize-thread.tsalready has 11 unformatted lines onmain; this change adds none, and both test files stay clean.🤖 Generated with Claude Code