pathwaycom/pathway · error · ValueError

Table.restrict(): other universe has to be a subset of self

Error message

Table.restrict(): other universe has to be a subset of self universe.Consider using Table.promise_universe_is_subset_of() to assert it.

What it means

Table.restrict(other) keeps only rows of self whose ids appear in other's universe, so other must be a subset. After a fast-path for identical universes (warning + return self), it verifies other._universe.is_subset_of(self._universe) and raises ValueError otherwise, suggesting Table.promise_universe_is_subset_of() to assert the relation when the check is too strict/expensive.

Source

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

        ...     '''
        ...   | cost
        ... 2 | 100
        ... 3 | 200
        ... '''
        ... )
        >>> t2.promise_universe_is_subset_of(t1)
        <pathway.Table schema={'cost': <class 'int'>}>
        >>> t3 = t1.restrict(t2)
        >>> pw.debug.compute_and_print(t3, include_id=False)
        age | owner | pet
        8   | Alice | 2
        9   | Bob   | 1
        """
        if self._universe == other._universe:
            warnings.warn("Identical universes for Table.restrict().", stacklevel=5)
            return self
        if not other._universe.is_subset_of(self._universe):
            raise ValueError(
                "Table.restrict(): other universe has to be a subset of self universe."
                + "Consider using Table.promise_universe_is_subset_of() to assert it."
            )
        if other._universe.is_equal_to(self._universe):
            warnings.warn(
                "Unnecessary call to Table.restrict(), consider using Table.with_universe_of().",
                stacklevel=5,
            )
        return self._restrict(other)

    @contextualized_operator
    def _restrict(self, other: TableLike) -> Table[TSchema]:
        context = clmn.RestrictContext(self._id_column, other._id_column)

        columns = {
            name: self._wrap_column_in_context(context, column, name)
            for name, column in self._columns.items()
        }

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Rebuild other from self's universe: derive t2 via operations on t1, or apply t2 = t2.with_universe_of(t1)-style alignment appropriate to your data
  2. If you are certain the subset relation holds (e.g. ids come from the same source), assert it: pw.Table.promise_universe_is_subset_of(t2, t1) before restrict
  3. Debug by intersecting: check a few ids from t2 against t1 to find where the universes diverge

Example fix

# before
t3 = t1.restrict(t2)  # t2 not a subset of t1 -> ValueError

# after
pw.Table.promise_universe_is_subset_of(t2, t1)
t3 = t1.restrict(t2)
Defensive patterns

Strategy: validation

Validate before calling

def is_subset(small, big) -> bool:
    return small._universe.is_subset_of(big._universe)

Type guard

import pathway as pw

def restrictable(sub: pw.Table, sup: pw.Table) -> bool:
    return sub._universe.is_subset_of(sup._universe)

Prevention

When it happens

Trigger: t1.restrict(t2) where t2 contains ids not present in t1 — e.g. t2 came from a different source, was reindexed (concat_reindex / new ids), or an outer-join result restricted against an inner table.

Common situations: Restricting a large table by a set computed from another connector; ids regenerated by an intermediate operation; graph/rewrite pipelines where universes drift.

Related errors


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