pola-rs/polars · error · ValueError

right join column {name!r} not found

Error message

right join column {name!r} not found

What it means

LazyFrame.update resolves other.collect_schema() and validates every right_on (or `on`) name against the right frame's schema; an unknown right key raises ValueError naming it. Note: `on` must exist in BOTH frames, so this also fires when the shared key is missing only on the right.

Source

Thrown at py-polars/src/polars/lazyframe/frame.py:9405

        else:
            # move on into left/right_on to simplify logic
            left_on = right_on = on

        if isinstance(left_on, str):
            left_on = [left_on]
        if isinstance(right_on, str):
            right_on = [right_on]

        left_schema = self.collect_schema()
        for name in left_on:
            if name not in left_schema:
                msg = f"left join column {name!r} not found"
                raise ValueError(msg)
        right_schema = other.collect_schema()
        for name in right_on:
            if name not in right_schema:
                msg = f"right join column {name!r} not found"
                raise ValueError(msg)

        # no need to join if *only* join columns are in other (inner/left update only)
        if how != "full" and len(right_schema) == len(right_on):
            if row_index_name is not None:
                return self.drop(row_index_name)
            return self

        # only use non-idx right columns present in left frame
        right_other = set(right_schema).intersection(left_schema) - set(right_on)

        # When include_nulls is True, we need to distinguish records after the join that
        # were originally null in the right frame, as opposed to records that were null
        # because the key was missing from the right frame.
        # Add a validity column to track whether row was matched or not.
        if include_nulls:
            validity = ("__POLARS_VALIDITY",)
            other = other.with_columns(F.lit(True).alias(validity[0]))
        else:

View on GitHub (pinned to df599052da)

Solutions

  1. Check other.collect_schema() and fix right_on to the exact right-frame name
  2. If names differ, set left_on/right_on explicitly instead of `on`
  3. Rename in `other` first: other.rename({'old_key': 'id'})

Example fix

// before
lf.update(other, on='id')  # other's key is 'user_id'

// after
lf.update(other, left_on='id', right_on='user_id')
Defensive patterns

Strategy: validation

Validate before calling

right_keys = [on] if isinstance(on, str) else (on or right_on or [])
right_schema = other.collect_schema()
missing = [c for c in right_keys if c not in right_schema]
if missing:
    raise KeyError(f'right keys not in schema: {missing}; have {list(right_schema)}')

Prevention

When it happens

Trigger: lf.update(other, on='id') where `other` lacks 'id'; right_on='key_r' typo; the update source was rebuilt/renamed and the key column changed.

Common situations: The `other` frame comes from a different pipeline (file, join result) with different column names; version change of an upstream producer.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/f8032833b189842d. Report an issue: GitHub.