pathwaycom/pathway · error · ValueError
Expected a ColumnReference, found a string. Did you mean <ta
Error message
Expected a ColumnReference, found a string. Did you mean <table>.{arg} instead of {repr(arg)}? What it means
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.
Source
Thrown at python/pathway/internals/table.py:1252
args = (*args, instance)
if id is not None:
if len(args) == 0:
args = (id,)
elif len(args) > 1:
raise ValueError(
"Table.groupby() cannot have id argument when grouping by multiple columns."
)
elif args[0]._column != id._column:
raise ValueError(
"Table.groupby() received id argument and is grouped by a single column,"
+ " but the arguments are not equal.\n"
+ "Consider using <table>.groupby(id=...), skipping the positional argument."
)
for arg in args:
if not isinstance(arg, expr.ColumnReference):
if isinstance(arg, str):
raise ValueError(
f"Expected a ColumnReference, found a string. Did you mean <table>.{arg}"
+ f" instead of {repr(arg)}?"
)
else:
raise ValueError(
"All Table.groupby() arguments have to be a ColumnReference."
)
self._check_for_disallowed_types(*args)
return groupbys.GroupedTable.create(
table=self,
grouping_columns=args,
last_column_is_instance=instance is not None,
set_id=id is not None,
sort_by=sort_by,
_filter_out_results_of_forgetting=_filter_out_results_of_forgetting,
_skip_errors=_skip_errors,
_is_window=_is_window,View on GitHub (pinned to fa2f74a464)
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)
Example fix
# before
g = t.groupby('owner') # string -> ValueError
# after
g = t.groupby(t.owner)
# dynamic names:
g = t.groupby(*(getattr(t, n) for n in ['owner', 'pet'])) Defensive patterns
Strategy: type-guard
Validate before calling
from pathway.internals import expression as expr
def all_column_refs(args) -> bool:
return all(isinstance(a, expr.ColumnReference) for a in args) Type guard
from pathway.internals import expression as expr
def is_column_ref(arg) -> bool:
return isinstance(arg, expr.ColumnReference) Prevention
- Convert names to references with getattr(t, name) before groupby
- Remember Pathway groupby takes references, not strings (unlike pandas)
When it happens
Trigger: 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.
Common situations: Coming from pandas/Spark where groupby('col') is idiomatic; storing column names in config and forwarding them directly.
Related errors
- You cannot use {dep.to_column_expression()} in this reduce s
- You cannot use {dep.to_column_expression()} in this context.
- Expected a ColumnReference, found a string. Did you mean thi
- In JoinResult.groupby() all arguments have to be a ColumnRef
- Table.groupby() cannot have id argument when grouping by mul
AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15).
Data as JSON: /api/errors/e89ac42c482ef568.
Report an issue: GitHub.