{"record":{"id":"54fb39da3dd28a3c","repo":"huggingface/smolagents","slug":"cannot-save-objects-created-with-from-space-from","errorCode":null,"errorMessage":"Cannot save objects created with from_space, from_langchain or from_gradio, as this would create errors.","messagePattern":"Cannot save objects created with from_space, from_langchain or from_gradio, as this would create errors\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/smolagents/tools.py","lineNumber":349,"sourceCode":"                    args = match.group(1).strip()\n                    if args:  # If there are other arguments\n                        return f\"def forward(self, {args})\"\n                    return \"def forward(self)\"\n\n                return re.sub(pattern, replacement, source_code)\n\n            forward_source_code = forward_source_code.replace(self.name, \"forward\")\n            forward_source_code = add_self_argument(forward_source_code)\n            forward_source_code = forward_source_code.replace(\"@tool\", \"\").strip()\n            tool_code += \"\\n\\n\" + textwrap.indent(forward_source_code, \"    \")\n\n        else:  # If the tool was not created by the @tool decorator, it was made by subclassing Tool\n            if type(self).__name__ in [\n                \"SpaceToolWrapper\",\n                \"LangChainToolWrapper\",\n                \"GradioToolWrapper\",\n            ]:\n                raise ValueError(\n                    \"Cannot save objects created with from_space, from_langchain or from_gradio, as this would create errors.\"\n                )\n\n            validate_tool_attributes(self.__class__)\n\n            tool_code = \"from typing import Any, Optional\\n\" + instance_to_source(self, base_cls=Tool)\n\n        requirements = {el for el in get_imports(tool_code) if el not in sys.stdlib_module_names} | {\"smolagents\"}\n\n        tool_dict = {\"name\": self.name, \"code\": tool_code, \"requirements\": sorted(requirements)}\n\n        # Add output_schema if it exists\n        if hasattr(self, \"output_schema\") and self.output_schema is not None:\n            tool_dict[\"output_schema\"] = self.output_schema\n\n        return tool_dict\n\n    @classmethod","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/tools.py#L331-L367","documentation":"Tool.to_dict serializes a tool by extracting its Python source. Tools created dynamically via from_space, from_langchain, or from_gradio are thin wrappers around remote objects with no meaningful source, so saving them is refused with a ValueError.","triggerScenarios":"Calling tool.to_dict() (directly or via agent.save()/_get_tool_code) on a SpaceToolWrapper, LangChainToolWrapper, or GradioToolWrapper instance obtained from Tool.from_space(...), from_langchain(...), or from_gradio(...), then trying to save the agent.","commonSituations":"Building an agent with a Hugging Face Space tool and calling agent.save('dir') to persist or share it; mixing wrapped third-party tools with regular tools and serializing the whole agent.","solutions":["Remove the space/langchain/gradio-wrapped tool from the agent before saving, or save an agent that only contains tools defined by subclassing Tool or @tool","Persist the wrapper's configuration (space id, api_name) and recreate the tool with from_space on load instead of to_dict","Replace the wrapper with a real Tool subclass that calls the space/chain internally"],"exampleFix":"# before\ntool = Tool.from_space(\"black-forest-labs/FLUX.1-schnell\")\nagent = ToolCallingAgent(tools=[tool])\nagent.save(\"out\")\n# after\n# persist creation params and rebuild at load time:\nimport json, pathlib\npathlib.Path(\"out/space.json\").write_text(json.dumps({\"repo_id\": \"black-forest-labs/FLUX.1-schnell\"}))\n# on load: tool = Tool.from_space(**json.loads(pathlib.Path(\"out/space.json\").read_text()))","handlingStrategy":"try-catch","validationCode":"WRAPPERS = {\"SpaceToolWrapper\", \"LangChainToolWrapper\", \"GradioToolWrapper\"}\nsavable = [t for t in agent.tools if type(t).__name__ not in WRAPPERS]","typeGuard":"def is_savable(tool) -> bool:\n    return type(tool).__name__ not in {\"SpaceToolWrapper\", \"LangChainToolWrapper\", \"GradioToolWrapper\"}","tryCatchPattern":"try:\n    agent.save(\"out\")\nexcept ValueError as e:\n    if \"Cannot save objects created with\" in str(e):\n        agent.tools = [t for t in agent.tools if is_savable(t)]\n        agent.save(\"out\")\n    else:\n        raise","preventionTips":["Keep dynamically wrapped tools out of agents you intend to serialize","Persist wrapper creation parameters (repo_id, api_name) and rebuild on load","Use source-defined tools (@tool or Tool subclass) when persistence matters"],"tags":["smolagents","serialization","from-space","wrapper"],"backgroundTag":"non-serializable-object","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}