{"record":{"id":"67d248ebfc4fee93","repo":"huggingface/smolagents","slug":"tool-validation-failed-for-cls-name-n","errorCode":null,"errorMessage":"Tool validation failed for {cls.__name__}:\\n","messagePattern":"Tool validation failed for (.+?):\\\\n","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tool_validation.py","lineNumber":262,"sourceCode":"        errors.append(\n            f\"Parameters in __init__ must have default values, found required parameters: \"\n            f\"{', '.join(class_level_checker.non_defaults)}\"\n        )\n    if class_level_checker.non_literal_defaults:\n        errors.append(\n            f\"Parameters in __init__ must have literal default values, found non-literal defaults: \"\n            f\"{', '.join(class_level_checker.non_literal_defaults)}\"\n        )\n\n    # Run checks on all methods\n    for node in class_node.body:\n        if isinstance(node, ast.FunctionDef):\n            method_checker = MethodChecker(class_level_checker.class_attributes, check_imports=check_imports)\n            method_checker.visit(node)\n            errors += [f\"- {node.name}: {error}\" for error in method_checker.errors]\n\n    if errors:\n        raise ValueError(f\"Tool validation failed for {cls.__name__}:\\n\" + \"\\n\".join(errors))\n    return\n","sourceCodeStart":244,"sourceCodeEnd":264,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tool_validation.py#L244-L264","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nclass MyTool(Tool):\n    client = OpenAI()  # invalid class attribute\n\n# after\nclass MyTool(Tool):\n    def setup(self):\n        self.client = OpenAI()","handlingStrategy":"validation","validationCode":"try:\n    validate_tool_attributes(MyTool)\n    valid = True\nexcept ValueError as e:\n    valid = False\n    issues = str(e)","typeGuard":null,"tryCatchPattern":"try:\n    validate_tool_attributes(MyTool)\nexcept ValueError as e:\n    for line in str(e).splitlines()[1:]:\n        print(\"fix:\", line)  # each '- name: error' line\n    raise","preventionTips":["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"],"tags":["smolagents","tool-validation","linting"],"backgroundTag":"tool-validation-failed","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}