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
- Define the tool/class as a top-level def/class in a cell (or module) and keep its name unchanged
- Assign __source__ manually: MyTool.__source__ = 'class MyTool(Tool): ...'
- 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
- Define tools as top-level class/def with stable names
- Set __source__ on factory-generated tools
- Avoid renaming or deleting defining cells before serialization
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
- No active IPython shell found
- No code cells found in IPython session
- Unknown model class '{model_info['class']}'. Supported model
- Cannot serialize object: {e}
- Pickle data rejected: allow_pickle=False requires safe-only
AI-assisted analysis of huggingface/smolagents@30bb116109 (2026-08-28).
Data as JSON: /api/errors/a6048a9f0a5490ab.
Report an issue: GitHub.