{"record":{"id":"36dc34ae5f57c699","repo":"pandas-dev/pandas","slug":"func-is-not-a-valid-function-for-type-obj","errorCode":null,"errorMessage":"'{func}' is not a valid function for '{type(obj).__name__}' object","messagePattern":"'(.+?)' is not a valid function for '(.+?)' object","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":846,"sourceCode":"        assert isinstance(func, str)\n\n        if hasattr(obj, func):\n            f = getattr(obj, func)\n            if callable(f):\n                return f(*args, **kwargs)\n\n            # people may aggregate on a non-callable attribute\n            # but don't let them think they can pass args to it\n            assert len(args) == 0\n            assert not any(kwarg == \"axis\" for kwarg in kwargs)\n            return f\n        elif hasattr(np, func) and hasattr(obj, \"__array__\"):\n            # in particular exclude Window\n            f = getattr(np, func)\n            return f(obj, *args, **kwargs)\n        else:\n            msg = f\"'{func}' is not a valid function for '{type(obj).__name__}' object\"\n            raise AttributeError(msg)\n\n\nclass NDFrameApply(Apply):\n    \"\"\"\n    Methods shared by FrameApply and SeriesApply but\n    not GroupByApply or ResamplerWindowApply\n    \"\"\"\n\n    obj: DataFrame | Series\n\n    @property\n    def index(self) -> Index:\n        return self.obj.index\n\n    @property\n    def agg_axis(self) -> Index:\n        return self.obj._get_agg_axis(self.axis)\n","sourceCodeStart":828,"sourceCodeEnd":864,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/apply.py#L828-L864","documentation":"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.","triggerScenarios":"`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).","commonSituations":"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.","solutions":["Check the spelling against the object's API (e.g. `dir(obj)` or pandas docs).","If you meant a custom function, pass the callable, not its name: `df.apply(my_func)` not `df.apply('my_func')`.","If you meant a numpy function, ensure the object supports `__array__` (e.g. cast via `.to_numpy()`)."],"exampleFix":"// before\ndf.agg('meean')\n// after\ndf.agg('mean')","handlingStrategy":"validation","validationCode":"def resolve_str_func(obj, func):\n    import numpy as np\n    if hasattr(obj, func):\n        return getattr(obj, func)\n    if hasattr(np, func) and hasattr(obj, '__array__'):\n        return getattr(np, func)\n    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]}')","typeGuard":"def str_func_exists(obj, func) -> bool:\n    import numpy as np\n    return hasattr(obj, func) or (hasattr(np, func) and hasattr(obj, '__array__'))","tryCatchPattern":"try:\n    out = df.agg(func)\nexcept AttributeError as e:\n    if 'is not a valid function' in str(e):\n        # suggest closest match\n        import difflib\n        suggestion = difflib.get_close_matches(func, dir(df), n=1)\n        raise AttributeError(f'{func!r} not found. Did you mean {suggestion}?') from e\n    raise","preventionTips":["Autocomplete or check docs for method names before passing as strings.","Pass the callable itself for custom functions, not the name.","Wrap string-dispatch in a helper that suggests close matches."],"tags":["pandas","apply","string-dispatch","attributeerror","typo"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}