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

  1. Omit name and let it default, ensuring target itself is identifier-safe
  2. Normalize the name: re.sub(r'\W|^(?=\d)', '_', name) to replace invalid characters with underscores
  3. 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

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


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/66822b33d64f6e81. Report an issue: GitHub.