{"record":{"id":"60ad56c04aa98c78","repo":"pathwaycom/pathway","slug":"expected-a-columnreference-found-a-string-did-yo","errorCode":null,"errorMessage":"Expected a ColumnReference, found a string. Did you mean this.{arg} instead of {repr(arg)}?","messagePattern":"Expected a ColumnReference, found a string\\. Did you mean this\\.(.+?) instead of (.+?)\\?","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/arg_handlers.py","lineNumber":184,"sourceCode":"\n        if \"right_exactly_once\" in kwargs:\n            processed_kwargs[\"right_exactly_once\"] = kwargs.pop(\"right_exactly_once\")\n\n        if kwargs:\n            raise ValueError(\n                \"Join received extra kwargs.\\n\"\n                + \"You probably want to use TableLike.join(...).select(**kwargs) to compute output columns.\"\n            )\n        return (self, other, *on), processed_kwargs\n\n    return handler\n\n\ndef reduce_args_handler(self, *args, **kwargs):\n    for arg in args:\n        if expr.smart_name(arg) is None:\n            if isinstance(arg, str):\n                raise ValueError(\n                    f\"Expected a ColumnReference, found a string. Did you mean this.{arg} instead of {repr(arg)}?\"\n                )\n            else:\n                raise ValueError(\n                    \"In reduce() all positional arguments have to be a ColumnReference.\"\n                )\n    return (self, *args), kwargs\n\n\ndef select_args_handler(self, *args, **kwargs):\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 this.{arg} instead of {repr(arg)}?\"\n                )\n            else:\n                raise ValueError(","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/arg_handlers.py#L166-L202","documentation":"Table.reduce()'s argument preprocessor requires every positional argument to be a ColumnReference with a resolvable name (expr.smart_name). When a bare string is passed, it raises this hint because the most common intent was referencing a column via table attribute access (e.g. this.col_name), not passing a string literal.","triggerScenarios":"Calling table.reduce(\"price\", sum_price=pw.reducers.sum(t.price)) or passing a column name string as a positional arg to keep that column in the output.","commonSituations":"Developers used to pandas agg/reset_index semantics where column names are strings; attempting to include a column by name in reduce output.","solutions":["Replace the string with a ColumnReference: table.reduce(t.key, sum_price=pw.reducers.sum(t.price)).","If referencing the table inside a method, use self.key or this.key rather than the literal name."],"exampleFix":"# before\nt.groupby(t.owner).reduce(\"owner\", total=pw.reducers.sum(t.price))\n\n# after\nt.groupby(t.owner).reduce(t.owner, total=pw.reducers.sum(t.price))","handlingStrategy":"type-guard","validationCode":"args_ok = all(hasattr(a, '_column') and hasattr(a, '_table') for a in args)\nassert args_ok, 'positional args to reduce() must be column references like t.col'","typeGuard":"import pathway.internals.expression as expr\n\ndef all_column_refs(args) -> bool:\n    return all(isinstance(a, expr.ColumnReference) for a in args)","tryCatchPattern":null,"preventionTips":["Never pass column names as strings to reduce/select; use t.name.","For dynamic names use getattr(t, name)."],"tags":["pathway","reduce","argument-validation","type-error"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}