huggingface/smolagents · error · ValueError
Tool validation failed for {cls.__name__}:\n
Error message
Tool validation failed for {cls.__name__}:\n What it means
validate_tool_attributes ran ClassLevelChecker and MethodChecker over the Tool subclass's AST and collected one or more rule violations (invalid class attributes, forbidden statements/imports in methods, etc.). It aggregates them into a single ValueError listing each offending method/attribute with a '- name: error' line. This is smolagents' guardrail ensuring tools stay serializable/safe when converted via to_dict or get_tools_definition_code.
Source
Thrown at src/smolagents/tool_validation.py:262
errors.append(
f"Parameters in __init__ must have default values, found required parameters: "
f"{', '.join(class_level_checker.non_defaults)}"
)
if class_level_checker.non_literal_defaults:
errors.append(
f"Parameters in __init__ must have literal default values, found non-literal defaults: "
f"{', '.join(class_level_checker.non_literal_defaults)}"
)
# Run checks on all methods
for node in class_node.body:
if isinstance(node, ast.FunctionDef):
method_checker = MethodChecker(class_level_checker.class_attributes, check_imports=check_imports)
method_checker.visit(node)
errors += [f"- {node.name}: {error}" for error in method_checker.errors]
if errors:
raise ValueError(f"Tool validation failed for {cls.__name__}:\n" + "\n".join(errors))
return
View on GitHub (pinned to 30bb116109)
Solutions
- Read each '- name: error' line in the message and fix the listed attribute/method first
- Move non-literal state from class attributes into __init__/setup instance attributes
- Restrict method bodies to supported literals/simple code; import modules at top level and avoid banned imports
- Pass check_imports=False only if you consciously need the flagged imports and accept the export limitations
Example fix
# before
class MyTool(Tool):
client = OpenAI() # invalid class attribute
# after
class MyTool(Tool):
def setup(self):
self.client = OpenAI() Defensive patterns
Strategy: validation
Validate before calling
try:
validate_tool_attributes(MyTool)
valid = True
except ValueError as e:
valid = False
issues = str(e) Try / catch
try:
validate_tool_attributes(MyTool)
except ValueError as e:
for line in str(e).splitlines()[1:]:
print("fix:", line) # each '- name: error' line
raise Prevention
- Keep class attributes as literals; init resources in setup()
- Import only allowed modules; avoid banned imports inside methods
- Run validate_tool_attributes in unit tests for every custom tool
When it happens
Trigger: Declaring class attributes that aren't allowed (e.g. non-literal defaults, arbitrary objects), using forbidden imports or statements inside forward/setup when check_imports is enabled, or multiple assignments to managed attributes; surfaces when calling to_dict or get_tools_definition_code on the tool class.
Common situations: Adding mutable/complex class-level state to a Tool (clients, dicts of objects), importing heavy or unsafe modules inside methods, defining closures/lambdas in tool methods; all of these break code-export of the tool.
Related errors
- Source code must define a class
- Error during jinja template rendering: {type(e).__name__}: {
- Cannot specify both 'messages' and 'steps' parameters. Use '
- The 'system_prompt' property is read-only. Use 'self.prompt_
- Agent name '{name}' must be a valid Python identifier and no
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/67d248ebfc4fee93.
Report an issue: GitHub.