{"record":{"id":"03913b5a516f4c78","repo":"agentscope-ai/agentscope","slug":"invalid-tool-name-mode-in-tool-choice-mode-av","errorCode":null,"errorMessage":"Invalid tool name '{mode}' in tool_choice.mode. Available tools in tool_choice.tools: {', '.join(sorted(tool_names))} / Available tools: {', '.join(sorted(available_functions))}","messagePattern":"Invalid tool name '(.+?)' in tool_choice\\.mode\\. Available tools in tool_choice\\.tools: (.+?) / Available tools: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/model/_base.py","lineNumber":358,"sourceCode":"\n        tool_names = tool_choice.tools\n        if tool_names is not None:\n            for name in tool_names:\n                if name not in available_functions:\n                    raise ValueError(\n                        f\"Invalid tool name '{name}' in tool_choice.tools. \"\n                        f\"Available tools: \"\n                        f\"{', '.join(sorted(available_functions))}\",\n                    )\n\n        if mode not in _TOOL_CHOICE_LITERAL_MODES:\n            # mode is a specific tool name — validate it exists\n            # Fall back to all available tools when tool_names is empty or None\n            validation_scope = (\n                tool_names if tool_names else available_functions\n            )\n            if mode not in validation_scope:\n                raise ValueError(\n                    f\"Invalid tool name '{mode}' in tool_choice.mode. \"\n                    + (\n                        f\"Available tools in tool_choice.tools: \"\n                        f\"{', '.join(sorted(tool_names))}\"\n                        if tool_names is not None\n                        else f\"Available tools: \"\n                        f\"{', '.join(sorted(available_functions))}\"\n                    ),\n                )\n\n    async def count_tokens(\n        self,\n        messages: list[Msg],\n        tools: list[dict] | None,\n    ) -> int:\n        \"\"\"A quick and unified method to estimate the token count of the\n        model input by dividing the total input size in bytes by 4.\n","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/model/_base.py#L340-L376","documentation":"Raised by agentscope's tool_choice validation when tool_choice.mode names a specific tool that is not in the set of tools passed to the model call. The validator checks the mode against tool_choice.tools (if provided) or against all functions registered with the agent/model; a mismatch means the named tool cannot be selected.","triggerScenarios":"Calling generate/reply with tool_choice={'mode': 'my_tool'} when 'my_tool' is not among the tools/schemas supplied in the same call (e.g. typo in the tool name, tool_choice.tools list not including it, or the toolkit not registered on the agent).","commonSituations":"Renaming a tool but forgetting to update tool_choice; specifying tool_choice.tools as a subset that excludes the tool named in mode; constructing tool_choice manually from a config string that doesn't match the registered function name.","solutions":["Check the error message: it lists valid tools; correct the mode string to exactly match a registered tool name","If using tool_choice.tools, ensure the tool named in mode is included in that list","Verify the toolkit/schemas are actually attached to the agent or passed as tools= before setting tool_choice","Print [t.name for t in agent.tools] (or the schemas you pass) to confirm exact spelling/casing"],"exampleFix":"// before\nawait agent(msg, tool_choice={'mode': 'seach_web'})  // typo\n\n// after\nawait agent(msg, tool_choice={'mode': 'search_web'})","handlingStrategy":"validation","validationCode":"valid = {t['function']['name'] for t in tools if isinstance(t, dict) and t.get('type') == 'function'}\nassert tool_choice['mode'] in valid, f\"mode must be one of {valid}\"","typeGuard":"def is_valid_tool_choice(tc: dict, tool_names: set[str]) -> bool:\n    return tc.get('mode') in tool_names or tc.get('mode') in ('auto', 'none', 'required')","tryCatchPattern":null,"preventionTips":["Derive tool_choice.mode programmatically from the registered tool list rather than hardcoding","Add a startup assertion that all configured tool names exist in the toolkit"],"tags":["agentscope","tool-choice","validation","tools"],"backgroundTag":"invalid-tool-choice","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}