huggingface/smolagents · error · ValueError
Cannot save objects created with from_space, from_langchain
Error message
Cannot save objects created with from_space, from_langchain or from_gradio, as this would create errors.
What it means
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.
Source
Thrown at src/smolagents/tools.py:349
args = match.group(1).strip()
if args: # If there are other arguments
return f"def forward(self, {args})"
return "def forward(self)"
return re.sub(pattern, replacement, source_code)
forward_source_code = forward_source_code.replace(self.name, "forward")
forward_source_code = add_self_argument(forward_source_code)
forward_source_code = forward_source_code.replace("@tool", "").strip()
tool_code += "\n\n" + textwrap.indent(forward_source_code, " ")
else: # If the tool was not created by the @tool decorator, it was made by subclassing Tool
if type(self).__name__ in [
"SpaceToolWrapper",
"LangChainToolWrapper",
"GradioToolWrapper",
]:
raise ValueError(
"Cannot save objects created with from_space, from_langchain or from_gradio, as this would create errors."
)
validate_tool_attributes(self.__class__)
tool_code = "from typing import Any, Optional\n" + instance_to_source(self, base_cls=Tool)
requirements = {el for el in get_imports(tool_code) if el not in sys.stdlib_module_names} | {"smolagents"}
tool_dict = {"name": self.name, "code": tool_code, "requirements": sorted(requirements)}
# Add output_schema if it exists
if hasattr(self, "output_schema") and self.output_schema is not None:
tool_dict["output_schema"] = self.output_schema
return tool_dict
@classmethodView on GitHub (pinned to 30bb116109)
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
Example fix
# before
tool = Tool.from_space("black-forest-labs/FLUX.1-schnell")
agent = ToolCallingAgent(tools=[tool])
agent.save("out")
# after
# persist creation params and rebuild at load time:
import json, pathlib
pathlib.Path("out/space.json").write_text(json.dumps({"repo_id": "black-forest-labs/FLUX.1-schnell"}))
# on load: tool = Tool.from_space(**json.loads(pathlib.Path("out/space.json").read_text())) Defensive patterns
Strategy: try-catch
Validate before calling
WRAPPERS = {"SpaceToolWrapper", "LangChainToolWrapper", "GradioToolWrapper"}
savable = [t for t in agent.tools if type(t).__name__ not in WRAPPERS] Type guard
def is_savable(tool) -> bool:
return type(tool).__name__ not in {"SpaceToolWrapper", "LangChainToolWrapper", "GradioToolWrapper"} Try / catch
try:
agent.save("out")
except ValueError as e:
if "Cannot save objects created with" in str(e):
agent.tools = [t for t in agent.tools if is_savable(t)]
agent.save("out")
else:
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unknown model class '{model_info['class']}'. Supported model
- Cannot serialize object: {e}
- Pickle data rejected: allow_pickle=False requires safe-only
- Could not find specified {api_name=} among available api nam
- No active IPython shell found
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/54fb39da3dd28a3c.
Report an issue: GitHub.