pathwaycom/pathway · error · ValueError
Universes of the arguments of Table.concat() have to be disj
Error message
Universes of the arguments of Table.concat() have to be disjoint. Consider using Table.promise_universes_are_disjoint() to assert it. (However, untrue assertion might result in runtime errors.)
What it means
Raised by Table._concat() when the universe solver cannot prove that the argument tables' row-id sets are pairwise disjoint. Vertical concatenation in Pathway is unsafe if two tables contain the same primary key, because the rows would collide. Pathway deliberately makes you assert disjointness explicitly.
Source
Thrown at python/pathway/internals/table.py:1675
)
id_type = _types_lca_with_error(
*[arg.schema._id_dtype for arg in all_args],
function_name="a concat",
pointers=True,
)
return Table._concat(
*[tab.cast_to_types(**schema).update_id_type(id_type) for tab in all_args]
)
@trace_user_frame
@contextualized_operator
def _concat(self, *others: Table[TSchema]) -> Table[TSchema]:
union_ids = (self._id_column, *(other._id_column for other in others))
if not self._get_universe_solver().query_are_disjoint(
*(c.universe for c in union_ids)
):
raise ValueError(
"Universes of the arguments of Table.concat() have to be disjoint.\n"
+ "Consider using Table.promise_universes_are_disjoint() to assert it.\n"
+ "(However, untrue assertion might result in runtime errors.)"
)
context = clmn.ConcatUnsafeContext(
union_ids=union_ids,
updates=tuple(
{col_name: other._columns[col_name] for col_name in self.keys()}
for other in others
),
)
return self._table_with_context(context)
@trace_user_frame
@check_arg_types
def update_cells(self, other: Table, _stacklevel: int = 1) -> Table:
"""Updates cells of `self`, breaking ties in favor of the values in `other`.
View on GitHub (pinned to fa2f74a464)
Solutions
- If the tables are provably disjoint, assert it: pw.Table.concat(t1.promise_universes_are_disjoint(), t2) — note the assertion only affects t2's relation to earlier args
- Regenerate ids on one side so they cannot collide: t2 = t2.with_id_from(...) or t2 = t2.with_id(pw.this.id + offset)
- If you actually want UNION-with-collision semantics, use update_cells/update_rows composition or a join-based merge instead of concat
- Verify overlap first with pw.debug.compute_and_print on both id sets in a small test
Example fix
# before t3 = pw.Table.concat(t1, t2) # ValueError: universes not disjoint # after (only if truly disjoint!) t3 = pw.Table.concat(t1, t2.promise_universes_are_disjoint()) # or force fresh ids t3 = pw.Table.concat(t1, t2.with_id_from(pw.this.make_ptr(t2.id, t2.name)))
Defensive patterns
Strategy: validation
Validate before calling
# Only assert when ids provably cannot overlap (e.g. distinct key ranges)
def disjoint_concat(t1, t2):
return pw.Table.concat(t1, t2.promise_universes_are_disjoint()) Try / catch
try:
t3 = pw.Table.concat(t1, t2)
except ValueError as e:
if 'have to be disjoint' in str(e):
t3 = pw.Table.concat(t1, t2.with_id_from(
pw.this.make_ptr(pw.this.id, 'source2')
)) Prevention
- Never concat tables whose ids derive from the same upstream ids
- Regenerate ids per branch before concat when in doubt
- Reserve promise_universes_are_disjoint for provable disjointness — a false assertion causes runtime errors
When it happens
Trigger: pw.Table.concat(t1, t2) where t1 and t2 may share ids (e.g. both derived from the same source, or ids generated from overlapping values); the solver returns query_are_disjoint(...) == False.
Common situations: Concatenating two streams derived from one upstream table (ids inherited); combining tables whose ids both come from pointer_from_string over overlapping keys; new users expecting SQL UNION-like semantics.
Related errors
- You cannot use {dep.to_column_expression()} in this context.
- not all arguments marked as iterated returned from iteration
- iterated table not marked as 'iterate_universe' changed its
- Universes of all arguments of Table.from_columns() have to b
- Universes of all arguments of Table.__add__() have to be equ
AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15).
Data as JSON: /api/errors/25bdecd5f8150b84.
Report an issue: GitHub.