huggingface/smolagents · error · ValueError

No code cells found in IPython session

Error message

No code cells found in IPython session

What it means

The IPython fallback in get_source found a shell, but shell.user_ns['In'] joined and stripped is empty — there are no executed input cells to search for the object's definition. This aborts AST scanning of notebook history.

Source

Thrown at src/smolagents/utils.py:415

        raise TypeError(f"Expected class or callable, got {type(obj)}")

    inspect_error = None
    try:
        # Handle dynamically created classes
        source = getattr(obj, "__source__", None) or inspect.getsource(obj)
        return dedent(source).strip()
    except OSError as e:
        # let's keep track of the exception to raise it if all further methods fail
        inspect_error = e
    try:
        import IPython

        shell = IPython.get_ipython()
        if not shell:
            raise ImportError("No active IPython shell found")
        all_cells = "\n".join(shell.user_ns.get("In", [])).strip()
        if not all_cells:
            raise ValueError("No code cells found in IPython session")

        tree = ast.parse(all_cells)
        for node in ast.walk(tree):
            if isinstance(node, (ast.ClassDef, ast.FunctionDef)) and node.name == obj.__name__:
                return dedent("\n".join(all_cells.split("\n")[node.lineno - 1 : node.end_lineno])).strip()
        raise ValueError(f"Could not find source code for {obj.__name__} in IPython history")
    except ImportError:
        # IPython is not available, let's just raise the original inspect error
        raise inspect_error
    except ValueError as e:
        # IPython is available but we couldn't find the source code, let's raise the error
        raise e from inspect_error


def encode_image_base64(image):
    buffered = BytesIO()
    image.save(buffered, format="PNG")
    return base64.b64encode(buffered.getvalue()).decode("utf-8")

View on GitHub (pinned to 30bb116109)

Solutions

  1. Define the class/tool in a notebook cell and execute it in the same kernel before calling serialization
  2. Prefer defining tools in importable modules so the inspect path succeeds
  3. Set obj.__source__ explicitly for dynamic objects

Example fix

# before
# fresh kernel, tool imported from elsewhere with broken inspect info
agent.to_dict()  # ValueError

# after
# run in a cell first:
class MyTool(Tool):
    ...
# then serialize
Defensive patterns

Strategy: fallback

Validate before calling

def ipython_has_history() -> bool:
    try:
        import IPython
        shell = IPython.get_ipython()
        return bool(shell and '\n'.join(shell.user_ns.get('In', [])).strip())
    except Exception:
        return False

Try / catch

try:
    src = get_source(obj)
except ValueError as e:
    if 'No code cells' in str(e):
        src = getattr(obj, '__source__', None)  # or define in a module instead

Prevention

When it happens

Trigger: A freshly started IPython kernel (only the auto 'In [1]' empty history) where code calls get_source on an object before any defining cell has run in that kernel.

Common situations: Objects imported from modules but inspect failing for another reason, then falling through to an empty notebook history; kernels restarted between definition and serialization.

Related errors


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