{"record":{"id":"dcd79e729f0f0cde","repo":"apache/beam","slug":"label","errorCode":null,"errorMessage":"label","messagePattern":"label","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/dataframe/frames.py","lineNumber":522,"sourceCode":"      grouping_columns = []\n      grouping_indexes = [0]\n\n    elif isinstance(by, np.ndarray):\n      raise frame_base.WontImplementError(\n          \"Grouping by a concrete ndarray is order sensitive.\",\n          reason=\"order-sensitive\")\n\n    elif isinstance(self, DeferredDataFrame):\n      if not isinstance(by, list):\n        by = [by]\n      # Find the columns that we need to move into the index so we can group by\n      # them\n      column_names = self._expr.proxy().columns\n      grouping_columns = list(set(by).intersection(column_names))\n      index_names = self._expr.proxy().index.names\n      for label in by:\n        if label not in index_names and label not in self._expr.proxy().columns:\n          raise KeyError(label)\n      grouping_indexes = list(set(by).intersection(index_names))\n\n      if grouping_indexes:\n        if set(by) == set(index_names):\n          to_group = self._expr\n        elif set(by).issubset(index_names):\n          to_group = self.droplevel(index_names.difference(by))._expr\n        else:\n          to_group = self.reset_index(grouping_indexes).set_index(by)._expr\n      else:\n        to_group = self.set_index(by)._expr\n\n      if grouping_columns:\n        # TODO(https://github.com/apache/beam/issues/20759):\n        # It should be possible to do this without creating\n        # an expression manually, by using DeferredDataFrame.set_index, i.e.:\n        #   to_group_with_index = self.set_index([self.index] +\n        #                                        grouping_columns)._expr","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/dataframe/frames.py#L504-L540","documentation":"In the deferred groupby implementation, when grouping 'by' a concrete NumPy ndarray, this WontImplementError fires: the message/label field identifies the unsupported operation because grouping by a raw ndarray is order-sensitive, which the Beam DataFrame API cannot guarantee under its partitioning semantics. Use a named column or list of columns instead.","triggerScenarios":"df.groupby('countrys') (typo) where the column is named 'country'; by list containing a label renamed upstream; grouping by a label that only exists after a previous transformation that was dropped.","commonSituations":"Schema drift after upstream pipeline changes; case-sensitivity mistakes ('Date' vs 'date'); grouping by a MultiIndex level name that was dropped by an earlier reset_index/droplevel.","solutions":["Fix the label spelling to match an actual column or index name","Verify available keys with df.columns and df.index.names before grouping","Select only the columns that exist: by=[c for c in wanted if c in df.columns]"],"exampleFix":"// before\ndf.groupby('Counrty')\n// after\nassert 'country' in df.columns\ndf.groupby('country')","handlingStrategy":"validation","validationCode":"cols = set(df.columns) | set(df.index.names)\nmissing = [b for b in by if b not in cols]\nif missing:\n    raise KeyError(f\"groupby keys not found: {missing}; have {sorted(cols)}\")","typeGuard":"def keys_exist(df, by):\n    names = set(df.columns) | set(df.index.names)\n    return all(b in names for b in (by if isinstance(by, (list, tuple)) else [by]))","tryCatchPattern":"try:\n    out = df.groupby(by)\nexcept KeyError as e:\n    logging.error(\"unknown groupby key %s; columns=%s index=%s\", e, list(df.columns), list(df.index.names))\n    raise","preventionTips":["Verify by labels against df.columns and df.index.names","Watch for schema drift from upstream transforms","Mind case sensitivity in column names"],"tags":["python","apache-beam","dataframe","keyerror"],"backgroundTag":"resource-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}