huggingface/smolagents · error · ImportError
No active IPython shell found
Error message
No active IPython shell found
What it means
When inspect.getsource fails (e.g. object defined in an interactive session), get_source falls back to searching IPython history. If IPython imports but IPython.get_ipython() returns None — no live shell in this process — this ImportError is raised, then re-raised as the original inspect error by the except ImportError handler.
Source
Thrown at src/smolagents/utils.py:412
TODO: handle Python standard REPL
"""
if not (isinstance(obj, type) or callable(obj)):
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):View on GitHub (pinned to 30bb116109)
Solutions
- Define the tool in a real .py module so inspect.getsource works
- Attach a __source__ attribute to dynamically created tools
- Run the serialization in the same process/session where the object was defined
- When in notebooks, run the defining cell in the same kernel before serializing
Example fix
# before
# tool defined with exec in a worker -> get_source fails
# after
# my_tools.py
def search(query: str) -> str:
...
search_tool = tool(search) Defensive patterns
Strategy: fallback
Validate before calling
import inspect
def has_recoverable_source(obj) -> bool:
try:
inspect.getsource(obj)
return True
except (OSError, TypeError):
return bool(getattr(obj, '__source__', None)) or _ipython_available_with_history() Type guard
def can_get_source(obj) -> bool:
import inspect
try:
inspect.getsource(obj)
return True
except Exception:
return getattr(obj, '__source__', None) is not None Try / catch
try:
src = get_source(obj)
except Exception as e:
if 'No active IPython' in str(e) or isinstance(e, OSError):
src = getattr(obj, '__source__', None) or fallback_repr(obj) Prevention
- Define tools in importable .py modules
- Attach __source__ to dynamically generated tools
- Serialize in the same process where objects were defined
When it happens
Trigger: Serializing a tool/class that was defined in a REPL/notebook-in-another-process: inspect has no source file, and get_source runs where no IPython shell exists (plain script, worker process).
Common situations: Using @tool in a subprocess or detached worker after pickling from a notebook; reloading modules so inspect loses file mappings; objects created via exec without __source__.
Related errors
- No code cells found in IPython session
- Could not find source code for {obj.__name__} in IPython his
- 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/16b9217648b7fe9b.
Report an issue: GitHub.