{"record":{"id":"e89ac42c482ef568","repo":"pathwaycom/pathway","slug":"expected-a-columnreference-found-a-string-did-yo-e89ac4","errorCode":null,"errorMessage":"Expected a ColumnReference, found a string. Did you mean <table>.{arg} instead of {repr(arg)}?","messagePattern":"Expected a ColumnReference, found a string\\. Did you mean <table>\\.(.+?) instead of (.+?)\\?","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/table.py","lineNumber":1252,"sourceCode":"            args = (*args, instance)\n        if id is not None:\n            if len(args) == 0:\n                args = (id,)\n            elif len(args) > 1:\n                raise ValueError(\n                    \"Table.groupby() cannot have id argument when grouping by multiple columns.\"\n                )\n            elif args[0]._column != id._column:\n                raise ValueError(\n                    \"Table.groupby() received id argument and is grouped by a single column,\"\n                    + \" but the arguments are not equal.\\n\"\n                    + \"Consider using <table>.groupby(id=...), skipping the positional argument.\"\n                )\n\n        for arg in args:\n            if not isinstance(arg, expr.ColumnReference):\n                if isinstance(arg, str):\n                    raise ValueError(\n                        f\"Expected a ColumnReference, found a string. Did you mean <table>.{arg}\"\n                        + f\" instead of {repr(arg)}?\"\n                    )\n                else:\n                    raise ValueError(\n                        \"All Table.groupby() arguments have to be a ColumnReference.\"\n                    )\n\n        self._check_for_disallowed_types(*args)\n        return groupbys.GroupedTable.create(\n            table=self,\n            grouping_columns=args,\n            last_column_is_instance=instance is not None,\n            set_id=id is not None,\n            sort_by=sort_by,\n            _filter_out_results_of_forgetting=_filter_out_results_of_forgetting,\n            _skip_errors=_skip_errors,\n            _is_window=_is_window,","sourceCodeStart":1234,"sourceCodeEnd":1270,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/table.py#L1234-L1270","documentation":"groupby() validates every positional argument is an expr.ColumnReference. Strings are given a dedicated message: ValueError('Expected a ColumnReference, found a string...') suggesting the attribute-access form. The guard exists because strings are silently meaningful in other APIs (e.g. __getitem__) and would otherwise be mistaken for column names here.","triggerScenarios":"t.groupby('owner') or t.groupby(['a','b']) — passing column names as strings or a list of strings instead of ColumnReference objects such as t.owner / pw.this.owner.","commonSituations":"Coming from pandas/Spark where groupby('col') is idiomatic; storing column names in config and forwarding them directly.","solutions":["Use attribute access: t.groupby(t.owner) or t.groupby(pw.this.owner)","Convert stored names via getattr: t.groupby(*(getattr(t, name) for name in names))","For multiple columns pass each as a reference: t.groupby(t.a, t.b)"],"exampleFix":"# before\ng = t.groupby('owner')  # string -> ValueError\n\n# after\ng = t.groupby(t.owner)\n# dynamic names:\ng = t.groupby(*(getattr(t, n) for n in ['owner', 'pet']))","handlingStrategy":"type-guard","validationCode":"from pathway.internals import expression as expr\n\ndef all_column_refs(args) -> bool:\n    return all(isinstance(a, expr.ColumnReference) for a in args)","typeGuard":"from pathway.internals import expression as expr\n\ndef is_column_ref(arg) -> bool:\n    return isinstance(arg, expr.ColumnReference)","tryCatchPattern":null,"preventionTips":["Convert names to references with getattr(t, name) before groupby","Remember Pathway groupby takes references, not strings (unlike pandas)"],"tags":["groupby","api-misuse","pathway"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}