microsoft/autogen · error · ValueError
Handoff name must be a valid identifier: {values['name']}
Error message
Handoff name must be a valid identifier: {values['name']} What it means
After confirming the supplied handoff name is a string, the same model_validator requires it to be a valid Python identifier (name.isidentifier()). This is because the name becomes the schema name of the handoff tool exposed to the LLM and must round-trip as a function/tool name. Non-identifier strings (hyphens, spaces, leading digits, dots) are rejected.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/base/_handoff.py:43
message: str = Field(default="")
"""The message to the target agent.
By default, it will be the result for the handoff tool.
If not provided, it is generated from the target agent's name."""
@model_validator(mode="before")
@classmethod
def set_defaults(cls, values: Dict[str, Any]) -> Dict[str, Any]:
if not values.get("description"):
values["description"] = f"Handoff to {values['target']}."
if not values.get("name"):
values["name"] = f"transfer_to_{values['target']}".lower()
else:
name = values["name"]
if not isinstance(name, str):
raise ValueError(f"Handoff name must be a string: {values['name']}")
# Check if name is a valid identifier.
if not name.isidentifier():
raise ValueError(f"Handoff name must be a valid identifier: {values['name']}")
if not values.get("message"):
values["message"] = (
f"Transferred to {values['target']}, adopting the role of {values['target']} immediately."
)
return values
@property
def handoff_tool(self) -> BaseTool[BaseModel, BaseModel]:
"""Create a handoff tool from this handoff configuration."""
def _handoff_tool() -> str:
return self.message
return FunctionTool(_handoff_tool, name=self.name, description=self.description, strict=True)
"""
The tool that can be used to handoff to the target agent.
Typically, the results of the tool's execution are provided to the target agent.View on GitHub (pinned to 027ecf0a37)
Solutions
- Omit name and let it default, ensuring target itself is identifier-safe
- Normalize the name: re.sub(r'\W|^(?=\d)', '_', name) to replace invalid characters with underscores
- Give agents identifier-friendly names (snake_case) at construction time so derived handoff names are valid
Example fix
# before Handoff(target="code reviewer", name="code-reviewer") # after import re name = re.sub(r'\W', '_', "code-reviewer") # 'code_reviewer' Handoff(target="code reviewer", name=name)
Defensive patterns
Strategy: validation
Validate before calling
def is_valid_handoff_name(name: str) -> bool:
return isinstance(name, str) and name.isidentifier() Type guard
def is_identifier_handoff_name(value) -> bool:
"""Narrow to names Handoff accepts: non-empty str and valid Python identifier."""
return isinstance(value, str) and value.isidentifier() Try / catch
import re
from autogen_agentchat.base import Handoff
try:
h = Handoff(target="writer", name=name)
except ValueError as e:
if "valid identifier" in str(e):
h = Handoff(target="writer", name=re.sub(r'\W|^(?=\d)', '_', name))
else:
raise Prevention
- Use snake_case handoff and agent names
- Sanitize externally sourced names with re.sub(r'\W', '_', name)
- Pre-validate names with str.isidentifier() in config loaders
When it happens
Trigger: Handoff(target='writer', name='handoff-to-writer') (hyphen); name='1st_agent' (leading digit); name='writer.agent' (dot); auto-generated names derived from targets containing spaces or unicode that is not identifier-safe (e.g. target='writing agent' produces 'transfer_to_writing agent'.lower()).
Common situations: Agent display names with spaces or hyphens being reused as handoff names; converting tool names from other frameworks (MCP, OpenAPI operationIds) that allow dashes; non-ASCII target names producing identifiers valid in Python but rejected downstream by some model providers.
Related errors
- Handoff name '{name}' is not a valid identifier.
- Handoff name must be a string: {values['name']}
- Agent name '{name}' is not a valid identifier.
- Handoff message target does not match agent name: {messages[
- At least one of max_total_token, max_prompt_token, or max_co
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/66822b33d64f6e81.
Report an issue: GitHub.