huggingface/smolagents · error · ValueError

Agent name '{name}' must be a valid Python identifier and no

Error message

Agent name '{name}' must be a valid Python identifier and not a reserved keyword.

What it means

Agent names must be valid Python identifiers and not reserved keywords, because agent names are used to expose managed agents as callable tools inside generated code. _validate_name rejects anything else with a ValueError during __init__.

Source

Thrown at src/smolagents/agents.py:366

            self.logger = logger

        self.monitor = Monitor(self.model, self.logger)
        self._setup_step_callbacks(step_callbacks)
        self.stream_outputs = False

    @property
    def system_prompt(self) -> str:
        return self.initialize_system_prompt()

    @system_prompt.setter
    def system_prompt(self, value: str):
        raise AttributeError(
            """The 'system_prompt' property is read-only. Use 'self.prompt_templates["system_prompt"]' instead."""
        )

    def _validate_name(self, name: str | None) -> str | None:
        if name is not None and not is_valid_name(name):
            raise ValueError(f"Agent name '{name}' must be a valid Python identifier and not a reserved keyword.")
        return name

    def _setup_managed_agents(self, managed_agents: list | None = None) -> None:
        """Setup managed agents with proper logging."""
        self.managed_agents = {}
        if managed_agents:
            assert all(agent.name and agent.description for agent in managed_agents), (
                "All managed agents need both a name and a description!"
            )
            self.managed_agents = {agent.name: agent for agent in managed_agents}
            # Ensure managed agents can be called as tools by the model: set their inputs and output_type
            for agent in self.managed_agents.values():
                agent.inputs = {
                    "task": {"type": "string", "description": "Long detailed description of the task."},
                    "additional_args": {
                        "type": "object",
                        "description": "Dictionary of extra inputs to pass to the managed agent, e.g. images, dataframes, or any other contextual data it may need.",
                        "nullable": True,

View on GitHub (pinned to 30bb116109)

Solutions

  1. Use a valid Python identifier: letters/digits/underscores, not starting with a digit, e.g. 'web_search_agent'
  2. Avoid Python keywords ('class', 'import', 'lambda', 'None', ...) as names
  3. If names come from external input, sanitize: re.sub(r'\W|^(?=\d)', '_', name) and check against keyword.kwlist

Example fix

# before
agent = WebSearchAgent(name="web-search")

# after
agent = WebSearchAgent(name="web_search")
Defensive patterns

Strategy: validation

Validate before calling

import keyword, re

def safe_agent_name(name: str) -> str:
    name = re.sub(r'\W|^(?=\d)', '_', name)
    if keyword.iskeyword(name):
        name += '_'
    return name

agent = MyAgent(name=safe_agent_name(raw_name))

Type guard

def is_valid_agent_name(name: str) -> bool:
    return name.isidentifier() and not keyword.iskeyword(name)

Prevention

When it happens

Trigger: Passing name='my agent', name='1agent', name='class', name='web-search', or a name with dashes/spaces/leading digits to MultiStepAgent/CodeAgent or a ManagedAgent; also non-ASCII or punctuation-containing names.

Common situations: Naming managed agents after domains like 'web-search' or 'text summarizer'; auto-generating names from task descriptions or file paths without sanitizing them.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/9ef4d6986af95605. Report an issue: GitHub.