{"record":{"id":"5bfe610cb7037262","repo":"langchain-ai/deepagents","slug":"context-tool-names-conflict-with-criteria-agent-to","errorCode":null,"errorMessage":"Context tool names conflict with criteria-agent tools: {names}.","messagePattern":"Context tool names conflict with criteria-agent tools: (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/goal_rubric.py","lineNumber":1685,"sourceCode":"        if isinstance(tool, BaseTool):\n            normalized_context_tools.append(tool)\n        elif inspect.iscoroutinefunction(tool):\n            normalized_context_tools.append(\n                StructuredTool.from_function(coroutine=tool)\n            )\n        else:\n            normalized_context_tools.append(StructuredTool.from_function(func=tool))\n\n    reserved_names = {_STRUCTURED_OUTPUT_TOOL_NAME}\n    if repository_backend is not None:\n        reserved_names.update(_REPOSITORY_TOOL_NAMES)\n    conflicting_names = sorted(\n        tool.name for tool in normalized_context_tools if tool.name in reserved_names\n    )\n    if conflicting_names:\n        names = \", \".join(conflicting_names)\n        msg = f\"Context tool names conflict with criteria-agent tools: {names}.\"\n        raise ValueError(msg)\n    middleware: list[AgentMiddleware[Any, Any]] = [\n        ConfigurableModelMiddleware(\n            persist_model_state=False,\n            cli_max_retries=cli_max_retries,\n        ),\n        _GoalContextFallbackMiddleware(),\n        _WebSearchBudgetMiddleware(),\n        _CriteriaContextBudgetMiddleware(),\n        CodeModelRetryMiddleware(max_retries=model_retries),\n    ]\n    if repository_backend is not None:\n        # Annotated (not `cast`) so the type checker validates each literal\n        # against `FsToolName` and rejects a typo at check time.\n        repository_tools: list[FsToolName] = [\"ls\", \"read_file\", \"glob\", \"grep\"]\n        if fs_tools is not None:\n            repository_tools = [name for name in repository_tools if name in fs_tools]\n        middleware.extend(\n            [","sourceCodeStart":1667,"sourceCodeEnd":1703,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/goal_rubric.py#L1667-L1703","documentation":"`_create_goal_criteria_agent` builds an internal sub-agent whose tool namespace contains reserved names: the structured-output tool and, when a repository backend is attached, the repository tool set. If caller-supplied `context_tools` include a tool whose name collides with a reserved name, the factory raises this `ValueError` listing the conflicting names.","triggerScenarios":"Calling `create_goal_criteria_agent`/`create_cli_agent` with `context_tools` containing a tool named like the structured-output tool or one of the repository tools (`_REPOSITORY_TOOL_NAMES`), including tools auto-wrapped from functions/coroutines whose function names collide.","commonSituations":"Passing the parent agent's full tool list (including repository/file tools) as context tools instead of a filtered subset; a custom tool accidentally named the same as a reserved repository tool; allowlist-intersection code that fails to exclude reserved names.","solutions":["Filter `context_tools` to exclude any tool whose name is in the reserved set before calling the factory.","Rename your custom tool to a distinct name that doesn't collide with repository or structured-output tool names.","If you intended repository tools in the sub-agent, pass the `repository_backend` instead of hand-listing its tools as context tools."],"exampleFix":"// before\nagent = create_goal_criteria_agent(context_tools=all_parent_tools)\n// after\nreserved = {structured_output_tool_name, *repository_tool_names}\nagent = create_goal_criteria_agent(context_tools=[t for t in all_parent_tools if t.name not in reserved])","handlingStrategy":"validation","validationCode":"reserved = {structured_output_tool_name} | set(repository_tool_names if repository_backend else [])\nconflicts = sorted(t.name for t in context_tools if t.name in reserved)\nif conflicts:\n    raise ValueError(f\"rename or drop tools conflicting with reserved names: {conflicts}\")","typeGuard":"def has_no_reserved_names(context_tools, reserved_names: set[str]) -> bool:\n    return not any(tool.name in reserved_names for tool in context_tools)","tryCatchPattern":"try:\n    agent = create_goal_criteria_agent(context_tools=tools, repository_backend=backend)\nexcept ValueError as e:\n    if \"conflict with criteria-agent tools\" in str(e):\n        tools = [t for t in tools if t.name not in reserved_names]\n        agent = create_goal_criteria_agent(context_tools=tools, repository_backend=backend)","preventionTips":["Never forward the parent agent's repository/file tools as context tools — pass `repository_backend` instead.","Prefix custom tools (e.g. `myorg_lookup`) to avoid accidental name collisions.","Keep the reserved-name check in a shared helper used by all sub-agent factories."],"tags":["configuration","naming-conflict","valueerror","tools"],"backgroundTag":"tool-name-conflict","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}