huggingface/smolagents · error · AttributeError
The 'system_prompt' property is read-only. Use 'self.prompt_
Error message
The 'system_prompt' property is read-only. Use 'self.prompt_templates["system_prompt"]' instead.
What it means
smolagents agents expose a read-only system_prompt property computed from the prompt_templates each time. Assigning agent.system_prompt = '...' raises AttributeError because the stored template would silently diverge from the computed prompt.
Source
Thrown at src/smolagents/agents.py:360
self.task: str | None = None
self.memory = AgentMemory(self.system_prompt)
if logger is None:
self.logger = AgentLogger(level=verbosity_level)
else:
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():View on GitHub (pinned to 30bb116109)
Solutions
- Set the template instead: agent.prompt_templates['system_prompt'] = 'your new template' (Jinja2-renderable)
- Or pass prompt_templates={'system_prompt': ...} / system_prompt at construction time
- Note templates are rendered with variables (tool descriptions, authorized imports), so use Jinja placeholders where needed
Example fix
# before
agent.system_prompt = "You are a helpful assistant."
# after
agent.prompt_templates["system_prompt"] = "You are a helpful assistant. Tools: {{ tool_descriptions }}" Defensive patterns
Strategy: validation
Validate before calling
def set_system_prompt(agent, template: str):
agent.prompt_templates["system_prompt"] = template # correct mutation point
assert agent.system_prompt # recompute/read works Prevention
- Treat system_prompt as read-only derived state
- Do all prompt customization via prompt_templates or constructor args
When it happens
Trigger: Executing agent.system_prompt = 'You are...' on any agent (ToolCallingAgent, CodeAgent, ManagedAgent); the setter always raises.
Common situations: Developers used to mutable prompt fields on other LLM frameworks try to tweak the system prompt after construction; attempting to customize a ManagedAgent's system prompt per-run by assignment.
Related errors
- Error during jinja template rendering: {type(e).__name__}: {
- Cannot specify both 'messages' and 'steps' parameters. Use '
- Agent name '{name}' must be a valid Python identifier and no
- Each tool or managed_agent should have a unique name! You pa
- step_callbacks must be a list or a dict
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/71228c6b750ab8c2.
Report an issue: GitHub.