langchain-ai/deepagents · error · ValueError
trusted_ask_user_tool must be named ask_user
Error message
trusted_ask_user_tool must be named ask_user
What it means
`AutoModeHITLMiddleware` accepts an optional `trusted_ask_user_tool` that is wired into the trusted tool surface, and it must literally be named `ask_user` so the middleware can recognize and route it. Passing a tool with a different name would break the trust assumptions of the HITL flow, so `__init__` raises this ValueError at construction time.
Source
Thrown at libs/code/deepagents_code/auto_mode.py:2162
A `provider:model` spec is resolved lazily (and cached) on the
first review; a chat model instance is used as-is. `None`
inherits the main agent model, which is the default. A per-run
`classifier_model` on the runtime context wins over this value.
cli_max_retries: Explicit `--max-retries` value to retain when a
distinct classifier model is constructed.
trusted_ask_user_tool: Built-in tool allowed to create consent receipts.
trusted_compaction_tool: Built-in tool that performs conversation
compaction.
Raises:
ValueError: If a trusted tool has an unexpected name.
"""
if (
trusted_ask_user_tool is not None
and trusted_ask_user_tool.name != "ask_user"
):
msg = "trusted_ask_user_tool must be named ask_user"
raise ValueError(msg)
if (
trusted_compaction_tool is not None
and trusted_compaction_tool.name != "compact_conversation"
):
msg = "trusted_compaction_tool must be named compact_conversation"
raise ValueError(msg)
# The review deadline is a security control's budget, so reject a
# nonsensical one at the boundary rather than trusting every caller:
# a zero, negative, or NaN timeout expires immediately, silently turning
# Auto into "deny every gated batch, then escalate". Callers that read
# user config go through `resolve_auto_classifier_timeout`, which bounds
# the value; this guards programmatic construction.
for name, budget in (
("classifier_timeout_seconds", classifier_timeout_seconds),
(
"classifier_construction_timeout_seconds",
classifier_construction_timeout_seconds,
),View on GitHub (pinned to a1af029e6e)
Solutions
- Rename the tool so its `.name` attribute is exactly 'ask_user' before passing it.
- If the tool must keep a custom name, do not pass it as `trusted_ask_user_tool`; leave the parameter unset and register it through the normal tool path.
- When wrapping with `.as_tool()` or a decorator, restore the name: set `wrapped.name = 'ask_user'`.
Example fix
// before mw = AutoModeHITLMiddleware(trusted_ask_user_tool=StructuredTool(name='user_question', func=ask_fn)) // after mw = AutoModeHITLMiddleware(trusted_ask_user_tool=StructuredTool(name='ask_user', func=ask_fn))
Defensive patterns
Strategy: validation
Validate before calling
tool = get_trusted_ask_user_tool()
if tool is not None and tool.name != 'ask_user':
raise ValueError(f"fix: trusted_ask_user_tool name is {tool.name!r}, must be 'ask_user'") Type guard
def is_trusted_ask_user(tool: BaseTool | None) -> bool:
return tool is None or tool.name == 'ask_user' Try / catch
try:
mw = AutoModeHITLMiddleware(trusted_ask_user_tool=tool)
except ValueError as e:
if 'trusted_ask_user_tool must be named ask_user' in str(e):
tool.name = 'ask_user'
mw = AutoModeHITLMiddleware(trusted_ask_user_tool=tool)
else:
raise Prevention
- Never rename trusted tools; keep canonical names 'ask_user' and 'compact_conversation'.
- After wrapping a tool (as_tool/decorators), reset `.name` to the canonical value.
- Add a startup assertion that all trusted tools passed to the middleware have canonical names.
When it happens
Trigger: Constructing `AutoModeHITLMiddleware(trusted_ask_user_tool=<tool>)` where `<tool>.name != 'ask_user'` — e.g. passing a renamed or wrapped copy of the ask_user tool.
Common situations: Renaming the ask_user tool for branding; wrapping the tool in a decorator or `as_tool` call that changes `.name`; copying an example where the tool was configured with a custom name.
Related errors
- trusted_compaction_tool must be named compact_conversation
- Invalid agent name: {agent_name!r} is reserved for dcode's o
- tool_call_id must not be empty
- deny decisions require a reason
- trusted thread, turn, and tool-call identity are required
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/f7fca91e958f5395.
Report an issue: GitHub.