{"record":{"id":"a7db978aa65f37fb","repo":"huggingface/smolagents","slug":"write-this-method-in-your-subclass-of-tool","errorCode":null,"errorMessage":"Write this method in your subclass of `Tool`.","messagePattern":"Write this method in your subclass of `Tool`\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tools.py","lineNumber":229,"sourceCode":"\n            json_schema = _convert_type_hints_to_json_schema(self.forward, error_on_missing_type_hints=False)[\n                \"properties\"\n            ]  # This function will not raise an error on missing docstrings, contrary to get_json_schema\n            for key, value in self.inputs.items():\n                assert key in json_schema, (\n                    f\"Input '{key}' should be present in function signature, found only {json_schema.keys()}\"\n                )\n                if \"nullable\" in value:\n                    assert \"nullable\" in json_schema[key], (\n                        f\"Nullable argument '{key}' in inputs should have key 'nullable' set to True in function signature.\"\n                    )\n                if key in json_schema and \"nullable\" in json_schema[key]:\n                    assert \"nullable\" in value, (\n                        f\"Nullable argument '{key}' in function signature should have key 'nullable' set to True in inputs.\"\n                    )\n\n    def forward(self, *args, **kwargs):\n        raise NotImplementedError(\"Write this method in your subclass of `Tool`.\")\n\n    def __call__(self, *args, sanitize_inputs_outputs: bool = False, **kwargs):\n        if not self.is_initialized:\n            self.setup()\n\n        # Handle the arguments might be passed as a single dictionary\n        if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], dict):\n            potential_kwargs = args[0]\n\n            # If the dictionary keys match our input parameters, convert it to kwargs\n            if all(key in self.inputs for key in potential_kwargs):\n                args = ()\n                kwargs = potential_kwargs\n\n        if sanitize_inputs_outputs:\n            args, kwargs = handle_agent_input_types(*args, **kwargs)\n        outputs = self.forward(*args, **kwargs)\n        if sanitize_inputs_outputs:","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tools.py#L211-L247","documentation":"The base Tool.forward is abstract and raises NotImplementedError; every usable tool must override it. __call__ delegates to forward, so calling an un-subclassed or partially implemented Tool fails here.","triggerScenarios":"Instantiating Tool directly and calling it; subclassing Tool but naming the method 'run', '_forward', or misspelling 'forward'; forgetting to implement forward in a custom tool class.","commonSituations":"Following a tutorial and skipping the forward implementation; renaming methods during refactor; creating a Tool subclass skeleton to test setup() only.","solutions":["Implement def forward(self, ...) in your Tool subclass with parameters matching self.inputs","Subclass a more specific base (PipelineTool) which splits work into setup/forward_inputs/forward_output, or use the @tool decorator","Check for typos in the method name (it must be exactly 'forward')"],"exampleFix":"# before\nclass MyTool(Tool):\n    def run(self, query): return query\n# after\nclass MyTool(Tool):\n    def forward(self, query: str) -> str: return query","handlingStrategy":"type-guard","validationCode":"import inspect\ndef forward_implemented(cls) -> bool:\n    return cls.forward is not Tool.forward","typeGuard":"def is_callable_tool(tool) -> bool:\n    return type(tool).forward is not Tool.forward","tryCatchPattern":"try:\n    result = tool(\"input\")\nexcept NotImplementedError:\n    logger.error(\"%s is incomplete: implement forward()\", type(tool).__name__)","preventionTips":["Always implement forward in Tool subclasses; the method name must be exactly 'forward'","Consider the @tool decorator for simple function tools so no abstract method remains","Run a tiny call in unit tests to catch unimplemented tools early"],"tags":["smolagents","tool","not-implemented","abstract-method"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}