pola-rs/polars · error
expected `right_on` to be str or Expr, got {qualified_type_n
Error message
expected `right_on` to be str or Expr, got {qualified_type_name(right_on)!r} What it means
In DataFrame.join_asof, when `on` is None the right-hand key must be given as `right_on`, and it must be a single str or pl.Expr. Passing a list, tuple, pl.Series, numpy object, or another unsupported type raises TypeError with the qualified type name. Note the checks run in order (left_on first), so this specific error means left_on already passed validation.
Source
Thrown at py-polars/src/polars/dataframe/frame.py:8228
│ Netherlands ┆ 2018-08-01 ┆ 17.32 ┆ 910 │
│ Netherlands ┆ 2019-01-01 ┆ 17.4 ┆ 910 │
└─────────────┴────────────┴────────────┴──────┘
"""
require_same_type(self, other)
if on is not None:
if not isinstance(on, (str, pl.Expr)):
msg = (
f"expected `on` to be str or Expr, got {qualified_type_name(on)!r}"
)
raise TypeError(msg)
else:
if not isinstance(left_on, (str, pl.Expr)):
msg = f"expected `left_on` to be str or Expr, got {qualified_type_name(left_on)!r}"
raise TypeError(msg)
elif not isinstance(right_on, (str, pl.Expr)):
msg = f"expected `right_on` to be str or Expr, got {qualified_type_name(right_on)!r}"
raise TypeError(msg)
from polars.lazyframe.opt_flags import QueryOptFlags
return (
self.lazy()
.join_asof(
other.lazy(),
left_on=left_on,
right_on=right_on,
on=on,
by_left=by_left,
by_right=by_right,
by=by,
strategy=strategy,
suffix=suffix,
tolerance=tolerance,
allow_parallel=allow_parallel,
force_parallel=force_parallel,View on GitHub (pinned to df599052da)
Solutions
- Use exactly one column name or expression: df.join_asof(other, left_on='ts_left', right_on='ts_right')
- Move non-time match keys to by=/by_left=/by_right= instead of adding them to right_on
- Unpack dynamic key lists in your wrapper: right_on=keys[0] or assert len(keys) == 1
Example fix
# before out = df.join_asof(other, left_on='ts_l', right_on=['ts_r', 'sym']) # after out = df.join_asof(other, left_on='ts_l', right_on='ts_r', by='sym')
Defensive patterns
Strategy: type-guard
Validate before calling
from polars.expr import Expr
if on is None:
assert isinstance(left_on, (str, Expr)), 'left_on must be str or Expr'
assert isinstance(right_on, (str, Expr)), 'right_on must be str or Expr' Type guard
from polars.expr import Expr
def is_single_asof_key(v: object) -> bool:
return isinstance(v, (str, Expr)) Prevention
- Build asof key pairs as single names/exprs only; unpack sequences with keys[0] plus an assertion
- Validate both left_on and right_on together in one guard before calling
- Cover join_asof calls in type-checked code (mypy) — the runtime check is a backstop
When it happens
Trigger: df.join_asof(other, left_on='ts_left', right_on=['ts_right', 'id']); right_on=pl.Series(...); right_on=('ts_right',); forwarding right_on from a config that sometimes holds a list of names.
Common situations: Multi-key expectations carried over from DataFrame.join usage; parameterized join helpers where key arguments are built dynamically and may arrive as sequences; pandas merge_asof ports with left_on/right_on semantics.
Related errors
- expected `on` to be str or Expr, got {qualified_type_name(on
- expected `left_on` to be str or Expr, got {qualified_type_na
- expected `by_predicate` to be an expression, got {qualified_
- cannot select columns using key of type {qualified_type_name
- cannot select rows using key of type {qualified_type_name(ke
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/797fbb515de78e2f.
Report an issue: GitHub.