huggingface/smolagents · error · InterpreterError

Cannot unpack tuple of wrong size

Error message

Cannot unpack tuple of wrong size

What it means

After confirming the value is tuple-like, set_value checks len(target.elts) == len(value); a mismatch raises InterpreterError('Cannot unpack tuple of wrong size'). This is the sandbox's equivalent of ValueError: not enough/too many values to unpack.

Source

Thrown at src/smolagents/local_python_executor.py:813

    target: ast.AST,
    value: Any,
    state: dict[str, Any],
    static_tools: dict[str, Callable],
    custom_tools: dict[str, Callable],
    authorized_imports: list[str],
) -> None:
    if isinstance(target, ast.Name):
        if target.id in static_tools:
            raise InterpreterError(f"Cannot assign to name '{target.id}': doing this would erase the existing tool!")
        state[target.id] = value
    elif isinstance(target, ast.Tuple):
        if not isinstance(value, tuple):
            if hasattr(value, "__iter__") and not isinstance(value, (str, bytes)):
                value = tuple(value)
            else:
                raise InterpreterError("Cannot unpack non-tuple value")
        if len(target.elts) != len(value):
            raise InterpreterError("Cannot unpack tuple of wrong size")
        for i, elem in enumerate(target.elts):
            set_value(elem, value[i], state, static_tools, custom_tools, authorized_imports)
    elif isinstance(target, ast.Subscript):
        obj = evaluate_ast(target.value, state, static_tools, custom_tools, authorized_imports)
        key = evaluate_ast(target.slice, state, static_tools, custom_tools, authorized_imports)
        obj[key] = value
    elif isinstance(target, ast.Attribute):
        obj = evaluate_ast(target.value, state, static_tools, custom_tools, authorized_imports)
        setattr(obj, target.attr, value)


def evaluate_call(
    call: ast.Call,
    state: dict[str, Any],
    static_tools: dict[str, Callable],
    custom_tools: dict[str, Callable],
    authorized_imports: list[str],
) -> Any:

View on GitHub (pinned to 30bb116109)

Solutions

  1. Match the number of targets to the data or use star-capture: `a, *rest = value`
  2. Validate length first: `assert len(v) == 2` or `if len(v) == 2: a, b = v else: ...`
  3. Index explicitly when only some fields are needed: a = v[0]

Example fix

# before
code = "a, b = (1, 2, 3)"

# after
code = "a, *rest = (1, 2, 3)"
Defensive patterns

Strategy: validation

Validate before calling

def unpackable_len(v) -> int | None:
    if isinstance(v, tuple):
        return len(v)
    if hasattr(v, '__iter__') and not isinstance(v, (str, bytes)):
        try:
            return len(list(v))
        except TypeError:
            return None
    return None
# before executing: check expected arity at each unpack site

Try / catch

from smolagents.local_python_executor import InterpreterError
try:
    evaluate_python(code)
except InterpreterError as e:
    if 'wrong size' in str(e):
        code = code.replace('a, b = v', 'a, *rest = v')

Prevention

When it happens

Trigger: `a, b = (1, 2, 3)`, `a, b, c = (1, 2)`, or unpacking a tool result whose length differs from the target names; also applies to for-loop targets (for a, b in pairs) when some element has the wrong length.

Common situations: API/tool returns a variable-length list and the model hardcodes two names; JSON payload shape changed between runs; iterating rows where some rows have extra fields.

Related errors


AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28). Data as JSON: /api/errors/98fd5b05545d6df4. Report an issue: GitHub.