{"record":{"id":"3f956cf17f8df33d","repo":"pandas-dev/pandas","slug":"column-not-found-key","errorCode":null,"errorMessage":"Column not found: {key}","messagePattern":"Column not found: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"pandas/core/base.py","lineNumber":224,"sourceCode":"\n        if len(self.exclusions) > 0:\n            return self.obj._drop_axis(self.exclusions, axis=1)\n        else:\n            return self.obj\n\n    def __getitem__(self, key):\n        if self._selection is not None:\n            raise IndexError(f\"Column(s) {self._selection} already selected\")\n\n        if isinstance(key, (list, tuple, ABCSeries, ABCIndex, np.ndarray)):\n            if len(self.obj.columns.intersection(key)) != len(set(key)):\n                bad_keys = list(set(key).difference(self.obj.columns))\n                raise KeyError(f\"Columns not found: {str(bad_keys)[1:-1]}\")\n            return self._gotitem(list(key), ndim=2)\n\n        else:\n            if key not in self.obj:\n                raise KeyError(f\"Column not found: {key}\")\n            ndim = self.obj[key].ndim\n            return self._gotitem(key, ndim=ndim)\n\n    def _gotitem(self, key, ndim: int, subset=None):\n        \"\"\"\n        sub-classes to define\n        return a sliced object\n\n        Parameters\n        ----------\n        key : str / list of selections\n        ndim : {1, 2}\n            requested ndim of result\n        subset : object, default None\n            subset to act on\n        \"\"\"\n        raise AbstractMethodError(self)\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/base.py#L206-L242","documentation":"Raised by SelectionMixin.__getitem__ when a scalar (non-list-like) key is passed to a groupby/rolling/expanding/resample selection and key not in self.obj is true. This is the single-column selector path: grouped['col']. The check uses __contains__ on the DataFrame so it matches column labels only, not index values.","triggerScenarios":"df.groupby('a')['misspelled']; window objects such as df.rolling(2)['b'] where 'b' was dropped; selecting on a Series groupby (where there are no columns); using a numeric label on a string-columned DataFrame.","commonSituations":"Typos and case errors in column names; selecting after rename/drop without updating downstream code; passing an index label instead of a column label; whitespace from CSV headers.","solutions":["Verify the key with `key in df.columns` before selection.","Fix the spelling/case to match df.columns exactly.","Strip whitespace from headers at load time: pd.read_csv(...).rename(columns=str.strip).","If selecting by index position, use .iloc/.nth on the groupby object instead."],"exampleFix":"// before\ng = df.groupby('id')['valu']\n// after\nassert 'value' in df.columns, df.columns.tolist()\ng = df.groupby('id')['value']","handlingStrategy":"validation","validationCode":"if key not in df.columns:\n    raise KeyError(f'{key!r} not in {df.columns.tolist()}')\ngrouped = df.groupby('id')[key]","typeGuard":"def is_known_column(df, key) -> bool:\n    return key in df.columns","tryCatchPattern":null,"preventionTips":["Use df.columns membership checks before scalar selection on groupby/window objects.","Avoid hardcoding column names scattered through code; centralize them."],"tags":["key-error","column-selection","groupby","indexing","schema-mismatch"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}