pola-rs/polars · error · ValueError

you should pass the column to join on as an argument

Error message

you should pass the column to join on as an argument

What it means

LazyFrame.join_asof() requires the join key: either on= (applied to both frames) or both left_on= and right_on=. If neither combination is provided, polars raises ValueError before building the plan. Unlike regular join, join_asof has no default key inference.

Source

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

        │ str         ┆ date       ┆ f64        ┆ i64  │
        ╞═════════════╪════════════╪════════════╪══════╡
        │ Germany     ┆ 2016-03-01 ┆ 82.19      ┆ 4164 │
        │ Germany     ┆ 2018-08-01 ┆ 82.66      ┆ 4696 │
        │ Germany     ┆ 2019-01-01 ┆ 83.12      ┆ 4696 │
        │ Netherlands ┆ 2016-03-01 ┆ 17.11      ┆ 784  │
        │ Netherlands ┆ 2018-08-01 ┆ 17.32      ┆ 910  │
        │ Netherlands ┆ 2019-01-01 ┆ 17.4       ┆ 910  │
        └─────────────┴────────────┴────────────┴──────┘
        """
        require_same_type(self, other)

        if isinstance(on, (str, pl.Expr)):
            left_on = on
            right_on = on

        if left_on is None or right_on is None:
            msg = "you should pass the column to join on as an argument"
            raise ValueError(msg)

        if by is not None:
            by_left_ = [by] if isinstance(by, str) else by
            by_right_ = by_left_
        elif (by_left is not None) or (by_right is not None):
            by_left_ = [by_left] if isinstance(by_left, str) else by_left  # type: ignore[assignment]
            by_right_ = [by_right] if isinstance(by_right, str) else by_right  # type: ignore[assignment]

        else:
            # no by
            by_left_ = None
            by_right_ = None

        tolerance_str: str | None = None
        tolerance_num: float | int | None = None
        if isinstance(tolerance, str):
            tolerance_str = tolerance
        elif isinstance(tolerance, timedelta):

View on GitHub (pinned to df599052da)

Solutions

  1. Pass on='timestamp' when both frames use the same key column name
  2. Otherwise pass left_on='ts_left', right_on='ts_right' together
  3. In wrapper functions, validate that at least one key argument is set before delegating to join_asof

Example fix

# before
lf.join_asof(other, by='group')

# after
lf.join_asof(other, on='timestamp', by='group')
Defensive patterns

Strategy: validation

Validate before calling

if on is None and (left_on is None or right_on is None):
    raise ValueError('join_asof requires on=, or both left_on= and right_on=')
lf.join_asof(other, on=on, left_on=left_on, right_on=right_on)

Type guard

def has_asof_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_asof(other) with no key arguments; passing only left_on='ts' without right_on; keys held in variables that are unexpectedly None.

Common situations: Time-series joins (asof joins on timestamps) where the key column names differ per frame or were refactored; optional key parameters defaulting to None in wrapper functions.

Related errors


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