pandas-dev/pandas · error · AttributeError

'{func}' is not a valid function for '{type(obj).__name__}'

Error message

'{func}' is not a valid function for '{type(obj).__name__}' object

What it means

Raised as an `AttributeError` from `_apply_str` when the string `func` is neither an attribute on the target object nor a numpy function applicable via `__array__`. This is the catch-all failure for string-dispatch: pandas tries `getattr(obj, func)`, then `getattr(np, func)`, and only raises when both lookups fail.

Source

Thrown at pandas/core/apply.py:846

        assert isinstance(func, str)

        if hasattr(obj, func):
            f = getattr(obj, func)
            if callable(f):
                return f(*args, **kwargs)

            # people may aggregate on a non-callable attribute
            # but don't let them think they can pass args to it
            assert len(args) == 0
            assert not any(kwarg == "axis" for kwarg in kwargs)
            return f
        elif hasattr(np, func) and hasattr(obj, "__array__"):
            # in particular exclude Window
            f = getattr(np, func)
            return f(obj, *args, **kwargs)
        else:
            msg = f"'{func}' is not a valid function for '{type(obj).__name__}' object"
            raise AttributeError(msg)


class NDFrameApply(Apply):
    """
    Methods shared by FrameApply and SeriesApply but
    not GroupByApply or ResamplerWindowApply
    """

    obj: DataFrame | Series

    @property
    def index(self) -> Index:
        return self.obj.index

    @property
    def agg_axis(self) -> Index:
        return self.obj._get_agg_axis(self.axis)

View on GitHub (pinned to 3b7651241d)

Solutions

  1. Check the spelling against the object's API (e.g. `dir(obj)` or pandas docs).
  2. If you meant a custom function, pass the callable, not its name: `df.apply(my_func)` not `df.apply('my_func')`.
  3. If you meant a numpy function, ensure the object supports `__array__` (e.g. cast via `.to_numpy()`).

Example fix

// before
df.agg('meean')
// after
df.agg('mean')
Defensive patterns

Strategy: validation

Validate before calling

def resolve_str_func(obj, func):
    import numpy as np
    if hasattr(obj, func):
        return getattr(obj, func)
    if hasattr(np, func) and hasattr(obj, '__array__'):
        return getattr(np, func)
    raise AttributeError(f'{func!r} is not a valid method on {type(obj).__name__}; available: {[a for a in dir(obj) if not a.startswith("_")][:20]}')

Type guard

def str_func_exists(obj, func) -> bool:
    import numpy as np
    return hasattr(obj, func) or (hasattr(np, func) and hasattr(obj, '__array__'))

Try / catch

try:
    out = df.agg(func)
except AttributeError as e:
    if 'is not a valid function' in str(e):
        # suggest closest match
        import difflib
        suggestion = difflib.get_close_matches(func, dir(df), n=1)
        raise AttributeError(f'{func!r} not found. Did you mean {suggestion}?') from e
    raise

Prevention

When it happens

Trigger: `df.agg('typo')`, `df.apply('nonexistent_method')`, `series.transform('meean')` (typo), or passing a string that is a numpy ufunc name but the object has no `__array__` (e.g. some Window objects).

Common situations: Typos in method names, assuming a method exists on GroupBy/Window objects when it does not, or passing a custom function name as a string instead of the callable itself.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/36dc34ae5f57c699. Report an issue: GitHub.