{"record":{"id":"0e05416b11dad914","repo":"pandas-dev/pandas","slug":"nested-renamer-is-not-supported","errorCode":null,"errorMessage":"nested renamer is not supported","messagePattern":"nested renamer is not supported","errorType":"exception","errorClass":"SpecificationError","httpStatus":null,"severity":"error","filePath":"pandas/core/apply.py","lineNumber":794,"sourceCode":"        self, how: str, obj: DataFrame | Series, func: AggFuncTypeDict\n    ) -> AggFuncTypeDict:\n        \"\"\"\n        Handler for dict-like argument.\n\n        Ensures that necessary columns exist if obj is a DataFrame, and\n        that a nested renamer is not passed. Also normalizes to all lists\n        when values consists of a mix of list and non-lists.\n        \"\"\"\n        assert how in (\"apply\", \"agg\", \"transform\")\n\n        # Can't use func.values(); wouldn't work for a Series\n        if (\n            how == \"agg\"\n            and isinstance(obj, ABCSeries)\n            and any(is_list_like(v) for _, v in func.items())\n        ) or (any(is_dict_like(v) for _, v in func.items())):\n            # GH 15931 - deprecation of renaming keys\n            raise SpecificationError(\"nested renamer is not supported\")\n\n        if obj.ndim != 1:\n            # Check for missing columns on a frame\n            from pandas import Index\n\n            cols = Index(list(func.keys())).difference(obj.columns, sort=True)\n            if len(cols) > 0:\n                # GH 58474\n                raise KeyError(f\"Label(s) {list(cols)} do not exist\")\n\n        aggregator_types = (list, tuple, dict)\n\n        # if we have a dict of any non-scalars\n        # eg. {'A' : ['mean']}, normalize all to\n        # be list-likes\n        # Cannot use func.values() because arg may be a Series\n        if any(isinstance(x, aggregator_types) for _, x in func.items()):\n            new_func: AggFuncTypeDict = {}","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/apply.py#L776-L812","documentation":"Raised in `normalize_dictlike_arg` when a dict-like function spec contains nested dict values (a 'renamer'), e.g. `{'A': {'new_name': 'mean'}}`. This deprecated/removed pattern (GH 15931) let users rename outputs inline; the supported replacement is to specify output names via the outer dict keys and a flat list of functions as values.","triggerScenarios":"`df.agg({'A': {'renamed_A': 'mean'}})` — the value is itself a dict, which is treated as a nested renamer. Also `series.agg({'x': {'y': 'sum'}})` or any dict-of-dict input.","commonSituations":"Old tutorials/code predating GH 15931 using the renamer pattern; copy-paste from Stack Overflow answers; migrating from a version that warned to one that raises.","solutions":["Flatten the spec: use the outer key as the column, the value as a list of functions, then rename columns of the result afterward: `df.agg({'A': ['mean', 'sum']}).rename(columns={'A': 'renamed_A'})`.","If renaming per-function, post-process the resulting frame's columns or index.","Audit for any dict-valued entries in your agg spec and convert them to lists."],"exampleFix":"# before\ndf.agg({'A': {'renamed_A': 'mean'}})\n# after\nout = df.agg({'A': ['mean']})\nout.columns = ['renamed_A']","handlingStrategy":"validation","validationCode":"def flatten_spec(spec):\n    \"\"\"Reject or flatten nested-dict (renamer) specs.\"\"\"\n    out = {}\n    for k, v in spec.items():\n        if isinstance(v, dict):\n            raise ValueError(f'nested renamer at {k!r}; flatten to list of funcs')\n        out[k] = v\n    return out\n\n# usage\ndf.agg(flatten_spec(my_spec))","typeGuard":"def is_flat_spec(spec) -> bool:\n    return all(not isinstance(v, dict) for v in spec.values())","tryCatchPattern":"from pandas.errors import SpecificationError\ntry:\n    df.agg(spec)\nexcept SpecificationError as e:\n    if 'nested renamer' in str(e):\n        # flatten the spec manually then retry\n        ...\n    raise","preventionTips":["Never use dict-of-dict to rename outputs; rename columns/index afterward.","Audit old code for the {'col': {'new': 'func'}} pattern when upgrading pandas."],"tags":["pandas","agg","apply","specificationerror","nested-renamer","deprecation"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}