{"record":{"id":"6efe693db6d9b3a4","repo":"apache/beam","slug":"you-have-to-supply-one-of-by-and-level","errorCode":null,"errorMessage":"You have to supply one of 'by' and 'level'","messagePattern":"You have to supply one of 'by' and 'level'","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/dataframe/frames.py","lineNumber":391,"sourceCode":"\n    Aggregations grouping by a categorical column with ``observed=False`` set\n    are not currently parallelizable\n    (`Issue 21827 <https://github.com/apache/beam/issues/21827>`_).\n    \"\"\"\n    if not as_index:\n      raise NotImplementedError('groupby(as_index=False)')\n\n    if axis in (1, 'columns'):\n      return _DeferredGroupByCols(\n          expressions.ComputedExpression(\n              'groupbycols', lambda df: df.groupby(\n                  by, axis=axis, group_keys=group_keys, **kwargs), [self._expr],\n              requires_partition_by=partitionings.Arbitrary(),\n              preserves_partition_by=partitionings.Arbitrary()),\n          group_keys=group_keys)\n\n    if level is None and by is None:\n      raise TypeError(\"You have to supply one of 'by' and 'level'\")\n\n    elif level is not None:\n      if isinstance(level, (list, tuple)):\n        grouping_indexes = level\n      else:\n        grouping_indexes = [level]\n\n      grouping_columns = []\n\n      index = self._expr.proxy().index\n\n      # Translate to level numbers only\n      grouping_indexes = [\n          l if isinstance(l, int) else index.names.index(l)\n          for l in grouping_indexes\n      ]\n\n      if index.nlevels == 1:","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/dataframe/frames.py#L373-L409","documentation":"The Beam DataFrame API's groupby requires a grouping specification: pandas groupby needs either 'by' or 'level', and this guard in frames.py rejects calls where neither is supplied. It mirrors pandas' own error but is raised in the deferred (lazy) API before any expression is computed.","triggerScenarios":"df.groupby() with no arguments, or calling groupby(None, level=None) — e.g. a wrapper that conditionally builds by= but passes None when the condition fails.","commonSituations":"Programmatic construction of groupby kwargs where the key variable was never set; refactors removing by= while relying on a default level; copy-paste from code that grouped via level but dropped that argument.","solutions":["Pass by= with one or more column/index labels","Or pass level= (an int, name, or list) to group by index level(s)","Check that the variable feeding by= is not None before calling"],"exampleFix":"// before\ndf.groupby(by=key)\n# where key may be None\n// after\nif key is not None:\n    df.groupby(by=key)\nelse:\n    df.groupby(level=0)","handlingStrategy":"validation","validationCode":"if by is None and level is None:\n    raise ValueError(\"groupby requires 'by' or 'level'\")\nout = df.groupby(by=by, level=level)","typeGuard":"def has_group_key(by, level):\n    return by is not None or level is not None","tryCatchPattern":"try:\n    out = df.groupby(by=key)\nexcept TypeError as e:\n    if \"'by' and 'level'\" in str(e):\n        out = df.groupby(level=0)","preventionTips":["Default by= to a real column name in wrappers","Assert the group-key variable is not None before calling","Prefer level=0 for grouping purely on the index"],"tags":["python","apache-beam","dataframe","missing-argument"],"backgroundTag":"missing-required-argument","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"}