{"record":{"id":"936af16101b595b7","repo":"huggingface/smolagents","slug":"object-obj-has-no-attribute-func-name","errorCode":null,"errorMessage":"Object {obj} has no attribute {func_name}","messagePattern":"Object (.+?) has no attribute (.+?)","errorType":"error_code","errorClass":"InterpreterError","httpStatus":null,"severity":"error","filePath":"src/smolagents/local_python_executor.py","lineNumber":845,"sourceCode":"    state: dict[str, Any],\n    static_tools: dict[str, Callable],\n    custom_tools: dict[str, Callable],\n    authorized_imports: list[str],\n) -> Any:\n    if not isinstance(call.func, (ast.Call, ast.Lambda, ast.Attribute, ast.Name, ast.Subscript)):\n        raise InterpreterError(f\"This is not a correct function: {call.func}).\")\n\n    func, func_name = None, None\n\n    if isinstance(call.func, ast.Call):\n        func = evaluate_ast(call.func, state, static_tools, custom_tools, authorized_imports)\n    elif isinstance(call.func, ast.Lambda):\n        func = evaluate_ast(call.func, state, static_tools, custom_tools, authorized_imports)\n    elif isinstance(call.func, ast.Attribute):\n        obj = evaluate_ast(call.func.value, state, static_tools, custom_tools, authorized_imports)\n        func_name = call.func.attr\n        if not hasattr(obj, func_name):\n            raise InterpreterError(f\"Object {obj} has no attribute {func_name}\")\n        func = getattr(obj, func_name)\n    elif isinstance(call.func, ast.Name):\n        func_name = call.func.id\n        if func_name in state:\n            func = state[func_name]\n        elif func_name in static_tools:\n            func = static_tools[func_name]\n        elif func_name in custom_tools:\n            func = custom_tools[func_name]\n        elif func_name in ERRORS:\n            func = ERRORS[func_name]\n        else:\n            raise InterpreterError(\n                f\"Forbidden function evaluation: '{call.func.id}' is not among the explicitly allowed tools or defined/imported in the preceding code\"\n            )\n    elif isinstance(call.func, ast.Subscript):\n        func = evaluate_ast(call.func, state, static_tools, custom_tools, authorized_imports)\n        if not callable(func):","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/local_python_executor.py#L827-L863","documentation":"For method-style calls (obj.method(...)), evaluate_call resolves the object then checks hasattr(obj, func_name) and raises InterpreterError naming the object and missing attribute — mirroring AttributeError inside the sandbox, with the object's repr embedded in the message (which can be noisy for large objects).","triggerScenarios":"Executed code calls a method that doesn't exist on the receiver: `x.append(1)` when x is an int, `df.col_name()` typo, calling `.json()` on a plain dict, or calling a method on None (e.g. result is None and code does result.strip()).","commonSituations":"Tool returns None on failure and the model chains a method call on it; wrong type assumption (str vs list); pandas/numpy API mix-ups; version differences where a method was renamed/removed in a library the code imports.","solutions":["Guard before calling: `if x is not None and hasattr(x, 'append'): x.append(1)`","Verify the actual type with type(x) or isinstance and adapt the call","Fix the method name / use the correct API for the type (e.g. json.dumps instead of .json on a dict)"],"exampleFix":"# before\ncode = \"final_answer(result.strip())\"  # result may be None\n\n# after\ncode = \"final_answer(result.strip() if result else '')\"","handlingStrategy":"type-guard","validationCode":"def has_method(obj, name: str) -> bool:\n    return obj is not None and hasattr(obj, name) and callable(getattr(obj, name))","typeGuard":"def has_method(obj, name: str) -> bool:\n    return obj is not None and callable(getattr(obj, name, None))","tryCatchPattern":"from smolagents.local_python_executor import InterpreterError\ntry:\n    evaluate_python(code)\nexcept InterpreterError as e:\n    if 'has no attribute' in str(e):\n        code = add_none_guard(code)  # e.g. result.strip() -> result.strip() if result else ''","preventionTips":["Guard method chains on values that can be None (result.x() if result else default)","Verify types with isinstance/type() before calling type-specific methods","Pin library versions the generated code targets so method names don't shift"],"tags":["smolagents","attribute-error","method-call","none-safety","interpreter-error"],"backgroundTag":"attribute-missing","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}