huggingface/smolagents · error · TypeError

Expected class or callable, got {type(obj)}

Error message

Expected class or callable, got {type(obj)}

What it means

get_source(obj) requires a class or callable to extract its source via inspect/ast. Passing anything else (an instance used wrongly, an int, None, a module) raises this TypeError immediately before any inspection is attempted.

Source

Thrown at src/smolagents/utils.py:397

    In a dynamic environment (e.g.: Jupyter, IPython), if this fails,
    falls back to retrieving the source code from the current interactive shell session.

    Args:
        obj: A class or callable object (e.g.: function, method)

    Returns:
        str: The source code of the object, dedented and stripped

    Raises:
        TypeError: If object is not a class or callable
        OSError: If source code cannot be retrieved from any source
        ValueError: If source cannot be found in IPython history

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

View on GitHub (pinned to 30bb116109)

Solutions

  1. Pass the class or function itself, e.g. MyTool not MyTool()
  2. Guard call sites with isinstance(obj, type) or callable(obj) before calling
  3. Check for None/early-return failures upstream that produce the bad value

Example fix

# before
src = get_source(tool_instance)

# after
src = get_source(type(tool_instance))
Defensive patterns

Strategy: type-guard

Validate before calling

if not (isinstance(obj, type) or callable(obj)):
    raise TypeError('pass a class or function')
src = get_source(obj)

Type guard

def is_class_or_callable(obj) -> bool:
    return isinstance(obj, type) or callable(obj)

Try / catch

try:
    get_source(obj)
except TypeError as e:
    if 'Expected class or callable' in str(e):
        obj = type(obj) if not isinstance(obj, type) else obj
        src = get_source(obj)

Prevention

When it happens

Trigger: Calling smolagents.utils.get_source (or @tool-decorated serialization paths like instance_to_source) with a non-class, non-callable object such as get_source(42) or get_source(None).

Common situations: Programmatically iterating over objects and accidentally passing instances instead of their classes (obj instead of type(obj)); None leaking from a failed lookup.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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