{"record":{"id":"921a42adbc2c0189","repo":"langchain-ai/deepagents","slug":"trusted-thread-turn-and-tool-call-identity-are-r","errorCode":null,"errorMessage":"trusted thread, turn, and tool-call identity are required","messagePattern":"trusted thread, turn, and tool-call identity are required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/auto_mode.py","lineNumber":1091,"sourceCode":"        return artifact\n    finally:\n        with contextlib.suppress(OSError):\n            os.close(file_descriptor)\n        if not complete:\n            with contextlib.suppress(OSError):\n                file_path.unlink()\n\n\ndef _temp_artifact_tool_context(\n    runtime: ToolRuntime[Any, AutoModeState],\n) -> tuple[str, str, str, Sequence[object]]:\n    thread_key = _thread_key(runtime)\n    messages = runtime.state.get(\"messages\", [])\n    turn_id = _latest_turn_id(messages)\n    tool_call_id = runtime.tool_call_id\n    if thread_key is None or turn_id is None or not tool_call_id:\n        msg = \"trusted thread, turn, and tool-call identity are required\"\n        raise ValueError(msg)\n    return thread_key, turn_id, tool_call_id, messages\n\n\ndef _temp_artifact_command(\n    *, tool_name: str, tool_call_id: str, content: str, error: bool\n) -> Command[Any]:\n    return Command(\n        update={\n            \"messages\": [\n                ToolMessage(\n                    content=content,\n                    name=tool_name,\n                    tool_call_id=tool_call_id,\n                    status=\"error\" if error else \"success\",\n                )\n            ]\n        }\n    )","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/auto_mode.py#L1073-L1109","documentation":"Raised by `_temp_artifact_tool_context` when a temp-artifact tool (`create_temp_artifact`, `delete_temp_artifact`) runs without a complete trusted identity: the thread key is None, the latest turn id cannot be determined, or `runtime.tool_call_id` is empty. Auto mode only allows temp-file operations that it can attribute to a specific thread, turn, and tool call, to keep artifact lifecycle scoped and safe.","triggerScenarios":"Calling `create_temp_artifact` or `delete_temp_artifact` outside a normal managed model-call context — e.g. invoking the tool directly with a hand-built runtime that lacks `tool_call_id`, running in a thread whose state has no identifiable turn, or a custom harness that does not populate the runtime state `messages`.","commonSituations":"Embedding the auto-mode tools in a custom LangGraph agent without the auto-mode middleware that assigns turn ids and tool-call ids; calling the tool functions from scripts/tests with a mock runtime; resuming a thread whose messages were pruned so `_latest_turn_id` returns None.","solutions":["Invoke the tools through the normal agent run so the auto-mode middleware supplies `thread_key`, `turn_id`, and `tool_call_id`","If calling directly, construct the runtime with a valid `tool_call_id` and state messages containing an identifiable latest turn","Ensure thread state is not stripped of messages before the tool executes (check message pruning/trimming config)","In tests, use the library's runtime fixtures rather than a bare mock missing `tool_call_id`"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from deepagents_code import auto_mode\n\ndef can_call_temp_artifacts(runtime) -> bool:\n    return (\n        auto_mode._thread_key(runtime) is not None\n        and auto_mode._latest_turn_id(runtime.state.get(\"messages\", [])) is not None\n        and bool(getattr(runtime, \"tool_call_id\", \"\"))\n    )","typeGuard":"def has_tool_identity(runtime) -> bool:\n    return bool(getattr(runtime, \"tool_call_id\", None))","tryCatchPattern":"try:\n    result = create_temp_artifact(content=content, suffix=\".md\")\nexcept ValueError as exc:\n    if \"trusted thread, turn, and tool-call identity\" in str(exc):\n        run_via_agent_middleware_instead_of_direct_call()\n    else:\n        raise","preventionTips":["Always invoke temp-artifact tools through the normal agent/model-call path, not directly with a mock runtime","Do not prune all messages from thread state before tool execution","In tests, use the library's runtime fixtures that populate thread_key/turn_id/tool_call_id","Keep the auto-mode middleware installed in custom graphs"],"tags":["validation","tool-call","identity","auto-mode"],"backgroundTag":"missing-tool-call-identity","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}