langchain-ai/deepagents · error · ValueError

trusted thread, turn, and tool-call identity are required

Error message

trusted thread, turn, and tool-call identity are required

What it means

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.

Source

Thrown at libs/code/deepagents_code/auto_mode.py:1091

        return artifact
    finally:
        with contextlib.suppress(OSError):
            os.close(file_descriptor)
        if not complete:
            with contextlib.suppress(OSError):
                file_path.unlink()


def _temp_artifact_tool_context(
    runtime: ToolRuntime[Any, AutoModeState],
) -> tuple[str, str, str, Sequence[object]]:
    thread_key = _thread_key(runtime)
    messages = runtime.state.get("messages", [])
    turn_id = _latest_turn_id(messages)
    tool_call_id = runtime.tool_call_id
    if thread_key is None or turn_id is None or not tool_call_id:
        msg = "trusted thread, turn, and tool-call identity are required"
        raise ValueError(msg)
    return thread_key, turn_id, tool_call_id, messages


def _temp_artifact_command(
    *, tool_name: str, tool_call_id: str, content: str, error: bool
) -> Command[Any]:
    return Command(
        update={
            "messages": [
                ToolMessage(
                    content=content,
                    name=tool_name,
                    tool_call_id=tool_call_id,
                    status="error" if error else "success",
                )
            ]
        }
    )

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Invoke the tools through the normal agent run so the auto-mode middleware supplies `thread_key`, `turn_id`, and `tool_call_id`
  2. If calling directly, construct the runtime with a valid `tool_call_id` and state messages containing an identifiable latest turn
  3. Ensure thread state is not stripped of messages before the tool executes (check message pruning/trimming config)
  4. In tests, use the library's runtime fixtures rather than a bare mock missing `tool_call_id`
Defensive patterns

Strategy: validation

Validate before calling

from deepagents_code import auto_mode

def can_call_temp_artifacts(runtime) -> bool:
    return (
        auto_mode._thread_key(runtime) is not None
        and auto_mode._latest_turn_id(runtime.state.get("messages", [])) is not None
        and bool(getattr(runtime, "tool_call_id", ""))
    )

Type guard

def has_tool_identity(runtime) -> bool:
    return bool(getattr(runtime, "tool_call_id", None))

Try / catch

try:
    result = create_temp_artifact(content=content, suffix=".md")
except ValueError as exc:
    if "trusted thread, turn, and tool-call identity" in str(exc):
        run_via_agent_middleware_instead_of_direct_call()
    else:
        raise

Prevention

When it happens

Trigger: 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`.

Common situations: 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.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/921a42adbc2c0189. Report an issue: GitHub.