pathwaycom/pathway · error · ValueError

Table expected here.

Error message

Table expected here.

What it means

Table.ix() needs a context table to know which rows to evaluate the index expression against. It collects all tables referenced in the expression; if they are not all the same table, context stays None, and the fallback loop then requires every collected item to be an actual Table instance. ValueError('Table expected here.') means the expression mixes a non-Table joinable (e.g. a GroupedTable or grouped context leaked into the expression) with regular tables, so no single evaluation context can be chosen.

Source

Thrown at python/pathway/internals/table.py:1468

        ... 4 | owl
        ... ''')
        >>> ret = t_birds.select(t_birds.desc, latin=t_animals.ix(t_birds.id).genus)
        >>> pw.debug.compute_and_print(ret, include_id=False)
        desc   | latin
        hoopoe | atropos
        owl    | hercules
        """

        if context is None:
            all_tables = collect_tables(expression)
            if len(all_tables) == 0:
                context = thisclass.this
            elif all(tab == all_tables[0] for tab in all_tables):
                context = all_tables[0]
        if context is None:
            for tab in all_tables:
                if not isinstance(tab, Table):
                    raise ValueError("Table expected here.")
            if len(all_tables) == 0:
                raise ValueError("Const value provided.")
            context = all_tables[0]
            for tab in all_tables:
                assert context._universe.is_equal_to(tab._universe)
        if isinstance(context, groupbys.GroupedJoinable):
            context = thisclass.this
        if isinstance(context, thisclass.ThisMetaclass):
            return context._delayed_op(
                lambda table, expression: self.ix(
                    expression=expression,
                    optional=optional,
                    context=table,
                    allow_misses=allow_misses,
                ),
                expression=expression,
                qualname=f"{self}.ix(...)",
                name="ix",

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Make the ix expression reference exactly one table (or only pw.this) — join the needed tables beforehand
  2. Inside grouped reductions, reference only the grouped table's columns and perform cross-table lookups via a separate join
  3. Simplify: compute intermediate columns with with_columns before ix so the expression is a single column reference

Example fix

# before
val = prices.ix(rates.currency * prices.qty)  # mixes two tables -> ValueError

# after
joined = prices.join(rates, prices.currency == rates.currency)
val = joined.ix(joined.rate * joined.qty)
Defensive patterns

Strategy: validation

Validate before calling

import pathway as pw
from pathway.internals.expressions import dereference

def ix_expression_is_single_table(expr, context_table) -> bool:
    tables = pw.Table._collect_tables(expr) if hasattr(pw.Table, '_collect_tables') else []
    return all(t is context_table for t in tables) if tables else False

Prevention

When it happens

Trigger: Calling t.ix(expr) where expr references columns from several different tables, or uses a GroupedTable / pw.this from a grouped context alongside other tables; heterogeneous expressions inside reduce/ix callbacks.

Common situations: Building an ix lookup expression in a grouped reduce that also references an outer table; copy-pasted snippet mixing t1.col and t2.col in one expression passed to ix.

Related errors


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