pola-rs/polars · error · ValueError

must specify `on` OR `left_on` and `right_on`

Error message

must specify `on` OR `left_on` and `right_on`

What it means

LazyFrame.join() needs the join key(s): either on= or the pair left_on=/right_on=. Supplying none of them raises ValueError — unlike some engines, polars does not infer or default to matching on common column names here.

Source

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

                    how,
                    suffix,
                    validate,
                    maintain_order,
                    build_side=build_side,
                    coalesce=None,
                )
            )

        if uses_on:
            pyexprs = parse_into_list_of_expressions(on)
            pyexprs_left = pyexprs
            pyexprs_right = pyexprs
        elif uses_lr_on:
            pyexprs_left = parse_into_list_of_expressions(left_on)
            pyexprs_right = parse_into_list_of_expressions(right_on)
        else:
            msg = "must specify `on` OR `left_on` and `right_on`"
            raise ValueError(msg)

        return self._from_pyldf(
            self._ldf.join(
                other._ldf,
                pyexprs_left,
                pyexprs_right,
                allow_parallel,
                force_parallel,
                nulls_equal,
                how,
                suffix,
                validate,
                maintain_order,
                build_side,
                coalesce,
            )
        )

View on GitHub (pinned to df599052da)

Solutions

  1. Add on='key' for same-named keys, or left_on=/right_on= for differing names
  2. Validate config before building the join: fail fast with a clear config error
  3. For Cartesian products use how='cross' explicitly (which takes no keys)

Example fix

# before
lf.join(other, how='inner')

# after
lf.join(other, on='id', how='inner')
Defensive patterns

Strategy: validation

Validate before calling

if on is None and left_on is None and right_on is None:
    raise ValueError('config missing join key: set on= or left_on=/right_on=')
lf.join(other, on=on, left_on=left_on, right_on=right_on)

Type guard

def has_join_key(on, left_on, right_on) -> bool:
    return on is not None or (left_on is not None and right_on is not None)

Prevention

When it happens

Trigger: lf.join(other, how='inner') with no keys; keys expected to be picked up from a kwargs dict that was empty; refactoring that dropped the on= argument.

Common situations: Pipeline code where join keys come from config and the config entry is missing; quick experiments omitting keys.

Related errors


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