{"record":{"id":"71c7074f89e28725","repo":"pandas-dev/pandas","slug":"func-is-expected-but-received-in-kwargs","errorCode":null,"errorMessage":"func is expected but received {} in **kwargs.","messagePattern":"func is expected but received (.+?) in \\*\\*kwargs\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":2313,"sourceCode":"\n    Returns\n    -------\n    columns : List[str]\n        List of user-provided keys.\n    func : List[Union[str, callable[...,Any]]]\n        List of user-provided aggfuncs\n\n    Examples\n    --------\n    >>> validate_func_kwargs({\"one\": \"min\", \"two\": \"max\"})\n    (['one', 'two'], ['min', 'max'])\n    \"\"\"\n    tuple_given_message = \"func is expected but received {} in **kwargs.\"\n    columns = list(kwargs)\n    func = []\n    for col_func in kwargs.values():\n        if not (isinstance(col_func, str) or callable(col_func)):\n            raise TypeError(tuple_given_message.format(type(col_func).__name__))\n        func.append(col_func)\n    if not columns:\n        no_arg_message = \"Must provide 'func' or named aggregation **kwargs.\"\n        raise TypeError(no_arg_message)\n    return columns, func\n\n\ndef include_axis(op_name: Literal[\"agg\", \"apply\"], colg: Series | DataFrame) -> bool:\n    return isinstance(colg, ABCDataFrame) or (\n        isinstance(colg, ABCSeries) and op_name == \"agg\"\n    )\n","sourceCodeStart":2295,"sourceCodeEnd":2325,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/apply.py#L2295-L2325","documentation":"TypeError raised in validate_func_kwargs when named-aggregation kwargs contain a value that is neither a string nor callable. Named aggregation values must be aggregations (e.g. 'sum', np.mean, a lambda); anything else is treated as a misuse.","triggerScenarios":"df.agg(a=1); df.agg(x=[1, 2]); df.groupby('k').agg(result=5); passing a column name where the function should go.","commonSituations":"Confusing the column and function positions, e.g. df.agg(mycol='target_column') intending to select a column rather than name an aggregation.","solutions":["Make each kwarg value a function name or callable: df.agg(a='sum').","For column-specific aggregation use NamedAgg: df.agg(result=NamedAgg(column='mycol', aggfunc='sum')).","If the value is a list, ensure every element is callable or a string name."],"exampleFix":"# before\ndf.agg(a=1)\n# after\ndf.agg(a='sum')","handlingStrategy":"type-guard","validationCode":"def validate_named_agg_kwargs(kwargs):\n    bad = {k: type(v).__name__ for k, v in kwargs.items() if not (isinstance(v, str) or callable(v))}\n    if bad:\n        raise TypeError(f'non-callable agg values: {bad}')\n    return kwargs\n\ndf.agg(**validate_named_agg_kwargs(kwargs))","typeGuard":"def is_valid_agg_value(v) -> bool:\n    return isinstance(v, str) or callable(v)","tryCatchPattern":"try:\n    df.agg(**kwargs)\nexcept TypeError as e:\n    if 'func is expected' in str(e):\n        kwargs = {k: 'sum' for k in kwargs}  # or surface to user\n        df.agg(**kwargs)\n    else:\n        raise","preventionTips":["Validate named-agg values are str/callable before passing.","Use NamedAgg for column-specific aggregations to avoid column/function confusion."],"tags":["agg","named-aggregation","type-validation"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}