{"record":{"id":"f7fca91e958f5395","repo":"langchain-ai/deepagents","slug":"trusted-ask-user-tool-must-be-named-ask-user","errorCode":null,"errorMessage":"trusted_ask_user_tool must be named ask_user","messagePattern":"trusted_ask_user_tool must be named ask_user","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/auto_mode.py","lineNumber":2162,"sourceCode":"                A `provider:model` spec is resolved lazily (and cached) on the\n                first review; a chat model instance is used as-is. `None`\n                inherits the main agent model, which is the default. A per-run\n                `classifier_model` on the runtime context wins over this value.\n            cli_max_retries: Explicit `--max-retries` value to retain when a\n                distinct classifier model is constructed.\n            trusted_ask_user_tool: Built-in tool allowed to create consent receipts.\n            trusted_compaction_tool: Built-in tool that performs conversation\n                compaction.\n\n        Raises:\n            ValueError: If a trusted tool has an unexpected name.\n        \"\"\"\n        if (\n            trusted_ask_user_tool is not None\n            and trusted_ask_user_tool.name != \"ask_user\"\n        ):\n            msg = \"trusted_ask_user_tool must be named ask_user\"\n            raise ValueError(msg)\n        if (\n            trusted_compaction_tool is not None\n            and trusted_compaction_tool.name != \"compact_conversation\"\n        ):\n            msg = \"trusted_compaction_tool must be named compact_conversation\"\n            raise ValueError(msg)\n        # The review deadline is a security control's budget, so reject a\n        # nonsensical one at the boundary rather than trusting every caller:\n        # a zero, negative, or NaN timeout expires immediately, silently turning\n        # Auto into \"deny every gated batch, then escalate\". Callers that read\n        # user config go through `resolve_auto_classifier_timeout`, which bounds\n        # the value; this guards programmatic construction.\n        for name, budget in (\n            (\"classifier_timeout_seconds\", classifier_timeout_seconds),\n            (\n                \"classifier_construction_timeout_seconds\",\n                classifier_construction_timeout_seconds,\n            ),","sourceCodeStart":2144,"sourceCodeEnd":2180,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/auto_mode.py#L2144-L2180","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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'`."],"exampleFix":"// before\nmw = AutoModeHITLMiddleware(trusted_ask_user_tool=StructuredTool(name='user_question', func=ask_fn))\n// after\nmw = AutoModeHITLMiddleware(trusted_ask_user_tool=StructuredTool(name='ask_user', func=ask_fn))","handlingStrategy":"validation","validationCode":"tool = get_trusted_ask_user_tool()\nif tool is not None and tool.name != 'ask_user':\n    raise ValueError(f\"fix: trusted_ask_user_tool name is {tool.name!r}, must be 'ask_user'\")","typeGuard":"def is_trusted_ask_user(tool: BaseTool | None) -> bool:\n    return tool is None or tool.name == 'ask_user'","tryCatchPattern":"try:\n    mw = AutoModeHITLMiddleware(trusted_ask_user_tool=tool)\nexcept ValueError as e:\n    if 'trusted_ask_user_tool must be named ask_user' in str(e):\n        tool.name = 'ask_user'\n        mw = AutoModeHITLMiddleware(trusted_ask_user_tool=tool)\n    else:\n        raise","preventionTips":["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."],"tags":["validation","naming","auto-mode","constructor"],"backgroundTag":"trusted-tool-name-mismatch","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}