{"record":{"id":"f1eb277b64ef6716","repo":"pandas-dev/pandas","slug":"must-provide-func-or-named-aggregation-kwargs","errorCode":null,"errorMessage":"Must provide 'func' or named aggregation **kwargs.","messagePattern":"Must provide 'func' or named aggregation \\*\\*kwargs\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":2317,"sourceCode":"        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":2299,"sourceCodeEnd":2325,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/apply.py#L2299-L2325","documentation":"Raised by validate_func_kwargs (apply.py:2317) as a TypeError when no kwargs at all are provided to a named-aggregation-style call. The function is invoked when pandas is expecting named aggregation; if the kwargs dict is empty there is nothing to aggregate, so pandas raises a guidance message directing the user to supply func or named-agg kwargs.","triggerScenarios":"Calling an internal code path that delegates to validate_func_kwargs with an empty kwargs dict, or df.agg(**{}) / df.agg() on a path where named aggregation is expected. Triggered at apply.py:2315-2317 when not columns.","commonSituations":"Programmatically building named-agg kwargs and ending up with an empty dict; refactoring that strips all kwargs; calling resample/window.agg() without arguments; passing a precomputed spec variable that resolved to {}.","solutions":["Supply at least one kwarg in the named-aggregation form: df.agg(name=('col','sum')).","If you intended a positional func, pass it positionally instead of via kwargs: df.agg('sum').","Guard dynamic spec construction: if not spec: skip the agg call or supply a default like 'sum'."],"exampleFix":"// before\nspec = {}\ndf.agg(**spec)\n// after\nspec = {'total': ('a','sum')}\ndf.agg(**spec)","handlingStrategy":"validation","validationCode":"if not kwargs:\n    raise TypeError(\"named aggregation requires at least one kwarg; pass func positionally otherwise\")","typeGuard":"def named_agg_nonempty(kwargs: dict) -> bool:\n    return bool(kwargs)","tryCatchPattern":"try:\n    df.agg(**kwargs)\nexcept TypeError as e:\n    if \"Must provide 'func' or named aggregation\" in str(e):\n        df.agg('sum')\n    else:\n        raise","preventionTips":["Guard dynamic named-agg dicts: if empty, supply a positional func instead.","Treat an empty kwargs dict as a programmer error, not a no-op."],"tags":["pandas","agg","named-aggregation","missing-argument"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}