pola-rs/polars · error · ValueError

'left_on' requires corresponding 'right_on'

Error message

'left_on' requires corresponding 'right_on'

What it means

LazyFrame.join() requires left_on= and right_on= to be supplied as a pair. Passing only one of them raises ValueError, because a join needs a key for each side.

Source

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

        │ 3   ┆ 8.0 ┆ c   ┆ y     ┆ b         │
        │ 3   ┆ 8.0 ┆ c   ┆ z     ┆ d         │
        └─────┴─────┴─────┴───────┴───────────┘
        """
        require_same_type(self, other)

        if maintain_order is None:
            maintain_order = "none"

        uses_on = on is not None
        uses_left_on = left_on is not None
        uses_right_on = right_on is not None
        uses_lr_on = uses_left_on or uses_right_on
        if uses_on and uses_lr_on:
            msg = "cannot use 'on' in conjunction with 'left_on' or 'right_on'"
            raise ValueError(msg)
        elif uses_left_on != uses_right_on:
            msg = "'left_on' requires corresponding 'right_on'"
            raise ValueError(msg)

        if how == "outer":
            how = "full"
            issue_deprecation_warning(
                "use of `how='outer'` should be replaced with `how='full'`.",
                version="0.20.29",
            )
        elif how == "outer_coalesce":  # type: ignore[comparison-overlap]
            coalesce = True
            how = "full"
            issue_deprecation_warning(
                "use of `how='outer_coalesce'` should be replaced with `how='full', coalesce=True`.",
                version="0.20.29",
            )
        elif how == "cross":
            if uses_on or uses_lr_on:
                msg = "cross join should not pass join keys"
                raise ValueError(msg)

View on GitHub (pinned to df599052da)

Solutions

  1. Add the matching right_on='other_id' (or left_on= if that is the missing one)
  2. If key names are identical, simplify to on='key'
  3. When building kwargs dynamically, assert both or neither of left_on/right_on is present

Example fix

# before
lf.join(other, left_on='id')

# after
lf.join(other, left_on='id', right_on='id')
Defensive patterns

Strategy: validation

Validate before calling

if (left_on is None) != (right_on is None):
    raise ValueError('left_on and right_on must be passed together')
lf.join(other, on=on, left_on=left_on, right_on=right_on)

Type guard

def has_paired_lr_keys(left_on, right_on) -> bool:
    return (left_on is None) == (right_on is None)

Prevention

When it happens

Trigger: lf.join(other, left_on='id') missing right_on; conditional code that sets right_on only in one branch; typo'd parameter name (right_onn=...) leaving right_on as None.

Common situations: Asymmetric joins where the developer only thinks about the left frame; copy-paste edits that drop one side; dynamically built kwargs.

Related errors


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