pathwaycom/pathway · error · ValueError

In JoinResult.reduce() all positional arguments have to be a

Error message

In JoinResult.reduce() all positional arguments have to be a ColumnReference.

What it means

Non-string branch of JoinResult.reduce positional-arg validation: an argument is neither ColumnReference nor str (int, expression, reducer call, etc.), raising ValueError 'In JoinResult.reduce() all positional arguments have to be a ColumnReference.' Reduce on a JoinResult delegates to groupby().reduce(...), so the same rules apply.

Source

Thrown at python/pathway/internals/joins.py:909

        >>> t2 = pw.debug.table_from_markdown('''
        ...     cost  owner  pet size
        ... 11   100  Alice    3    M
        ... 12    90    Bob    1    L
        ... 13    80    Tom    1   XL
        ... ''')
        >>> result = t1.join(t2, t1.owner==t2.owner).reduce(total_pairs = pw.reducers.count())
        >>> pw.debug.compute_and_print(result, include_id=False)
        total_pairs
        3
        """
        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 this.{arg} instead of {repr(arg)}?"
                    )
                else:
                    raise ValueError(
                        "In JoinResult.reduce() all positional arguments have to be a ColumnReference."
                    )
        return self.groupby().reduce(*args, **kwargs)

    def _substitutions(
        self,
    ) -> tuple[Table, dict[expr.InternalColRef, expr.ColumnExpression]]:
        return self._inner_table, {
            int_ref: expression for int_ref, expression in self._columns_mapping.items()
        }

    @desugar
    @arg_handler(handler=select_args_handler)
    @contextualized_operator
    @staticmethod
    def _join(
        context: clmn.JoinContext, *args: expr.ColumnReference, **kwargs: Any
    ) -> Table:

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Materialize computed columns with with_columns/select before the join-level reduce
  2. Ensure every positional element is pw.this.<col> or <table>.<col>

Example fix

# before
res = t1.join(t2, t1.owner == t2.owner).reduce(t1.amount * 2, n=pw.reducers.count())

# after
base = t1.join(t2, t1.owner == t2.owner).with_columns(amount2=t1.amount * 2)
res = base.reduce(base.amount2, n=pw.reducers.count())
Defensive patterns

Strategy: type-guard

Validate before calling

from pathway.internals import expr

assert all(isinstance(a, expr.ColumnReference) for a in args), "positional reduce args must be column references"

Type guard

from pathway.internals import expr

def all_column_references(args) -> bool:
    return all(isinstance(a, expr.ColumnReference) for a in args)

Prevention

When it happens

Trigger: reduce(t1.owner + 1, n=pw.reducers.count()) or reduce(42, ...) — anything that is not a plain column reference in a positional slot.

Common situations: Trying to project a computed column directly in reduce; accidentally passing a list of names with * unpacking where some element is not a column reference.

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/6f3caf8651144ff4. Report an issue: GitHub.