agentscope-ai/agentscope · error · ValueError
Invalid tool name '{mode}' in tool_choice.mode. Available to
Error message
Invalid tool name '{mode}' in tool_choice.mode. Available tools in tool_choice.tools: {', '.join(sorted(tool_names))} / Available tools: {', '.join(sorted(available_functions))} What it means
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.
Source
Thrown at src/agentscope/model/_base.py:358
tool_names = tool_choice.tools
if tool_names is not None:
for name in tool_names:
if name not in available_functions:
raise ValueError(
f"Invalid tool name '{name}' in tool_choice.tools. "
f"Available tools: "
f"{', '.join(sorted(available_functions))}",
)
if mode not in _TOOL_CHOICE_LITERAL_MODES:
# mode is a specific tool name — validate it exists
# Fall back to all available tools when tool_names is empty or None
validation_scope = (
tool_names if tool_names else available_functions
)
if mode not in validation_scope:
raise ValueError(
f"Invalid tool name '{mode}' in tool_choice.mode. "
+ (
f"Available tools in tool_choice.tools: "
f"{', '.join(sorted(tool_names))}"
if tool_names is not None
else f"Available tools: "
f"{', '.join(sorted(available_functions))}"
),
)
async def count_tokens(
self,
messages: list[Msg],
tools: list[dict] | None,
) -> int:
"""A quick and unified method to estimate the token count of the
model input by dividing the total input size in bytes by 4.
View on GitHub (pinned to e90f1c7592)
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
Example fix
// before
await agent(msg, tool_choice={'mode': 'seach_web'}) // typo
// after
await agent(msg, tool_choice={'mode': 'search_web'}) Defensive patterns
Strategy: validation
Validate before calling
valid = {t['function']['name'] for t in tools if isinstance(t, dict) and t.get('type') == 'function'}
assert tool_choice['mode'] in valid, f"mode must be one of {valid}" Type guard
def is_valid_tool_choice(tc: dict, tool_names: set[str]) -> bool:
return tc.get('mode') in tool_names or tc.get('mode') in ('auto', 'none', 'required') Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Each schema must be a dict with 'type' as 'function' and 'fu
- Input validation failed for tool '{tool_call.name}': {e.mess
- The injection template must contain the '{runtime_state}' pl
- Expected a 5-field cron expression, got {record.data.cron_ex
- Input must be a list of Msg objects.
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/03913b5a516f4c78.
Report an issue: GitHub.