huggingface/smolagents · error · ValueError

Could not find source code for {obj.__name__} in IPython his

Error message

Could not find source code for {obj.__name__} in IPython history

What it means

The IPython fallback parsed all notebook cells but no top-level ast.ClassDef/FunctionDef node matches obj.__name__, so the source cannot be recovered. Note it only matches top-level definitions; nested or dynamically built objects will not be found.

Source

Thrown at src/smolagents/utils.py:421

        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")


def make_image_url(base64_image):
    return f"data:image/png;base64,{base64_image}"

View on GitHub (pinned to 30bb116109)

Solutions

  1. Define the tool/class as a top-level def/class in a cell (or module) and keep its name unchanged
  2. Assign __source__ manually: MyTool.__source__ = 'class MyTool(Tool): ...'
  3. Move the definition into an importable .py file

Example fix

# before
MyTool = type('MyTool', (Tool,), {...})  # never in history

# after
class MyTool(Tool):
    def forward(self, ...): ...
Defensive patterns

Strategy: fallback

Validate before calling

def object_in_ipython_history(obj) -> bool:
    import ast, IPython
    shell = IPython.get_ipython()
    if not shell:
        return False
    cells = '\n'.join(shell.user_ns.get('In', [])).strip()
    try:
        return any(
            isinstance(n, (ast.ClassDef, ast.FunctionDef)) and n.name == obj.__name__
            for n in ast.walk(ast.parse(cells))
        )
    except SyntaxError:
        return False

Try / catch

try:
    src = get_source(obj)
except ValueError as e:
    if 'Could not find source code' in str(e):
        src = getattr(obj, '__source__', None) or f'# source unavailable for {obj.__name__}'

Prevention

When it happens

Trigger: The object was created dynamically (type()/factory), renamed, defined inside another function/class, or its name-bearing cell was cleared before get_source ran.

Common situations: @tool-wrapped closures whose __name__ differs from any top-level def; tools built by loops generating classes; notebook cells deleted after execution.

Related errors


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