pola-rs/polars · critical
cross join filter holds no keys
Error message
cross join filter holds no keys
What it means
Internal Rust panic in polars-plan indicating that a cross join's filter was expected to hold join keys but the JoinType variant being mutated has no key slots. It fires when code calls the key-setting helper on a join type other than the variants that store left_on/right_on keys (e.g. Range). This is an invariant violation inside the query planner, not a user-input error.
Source
Thrown at crates/polars-plan/src/plans/options.rs:739
/// On [`Self::CrossAndFilter`], which holds no keys, or on a length mismatch where the
/// variant stores keys in pairs.
pub fn set_keys(&mut self, left: Vec<ExprIR>, right: Vec<ExprIR>) {
if let Some(on) = self.key_pairs_mut() {
*on = left.into_iter().zip_eq(right).collect();
return;
}
match self {
#[cfg(feature = "iejoin")]
Self::IEJoin {
left_on, right_on, ..
}
| Self::Range {
left_on, right_on, ..
} => {
*left_on = left;
*right_on = right;
},
_ => panic!("cross join filter holds no keys"),
}
}
/// The match condition is exactly `left == right` for every key pair.
///
/// True for [`Self::AsOf`] too: its strategy and tolerance live in [`JoinType::AsOf`],
/// not in the match condition. False once a fused predicate is attached.
pub fn is_pure_equi(&self) -> bool {
!self.is_non_equi()
}
/// The match condition has a non-equality component.
///
/// Use [`Self::key_pairs`] instead where what is needed is paired keys: a fused predicate
/// join has those as well.
pub fn is_non_equi(&self) -> bool {
self.key_pairs().is_none() || self.has_fused_predicate()
}View on GitHub (pinned to 68506541d2)
Solutions
- If you are a polars contributor: handle the new/remaining JoinType variants explicitly instead of the wildcard _ arm
- Verify the JoinType is one that holds keys (Range/I Equi variants) before calling the setter
- If hit from Python, minimize the reproducing query and report it as a polars bug with the query plan
- Check you are on the latest polars release; planner panics are often fixed quickly
Example fix
// before
(join_type, keys) = match join_type { _ => panic!("cross join filter holds no keys") }
// after
match join_type {
Self::Range { left_on, right_on, .. } => { *left_on = left; *right_on = right; },
other => return Err(PolarsError::InvalidOperation("join type holds no keys".into())),
} Defensive patterns
Strategy: validation
Prevention
- Pin a stable polars release in production
- Add regression tests covering join configurations you rely on
- Report planner panics upstream with a minimal reproducer
When it happens
Trigger: Calling the internal key-assignment API (the method containing 'Self::Range { left_on, right_on, .. }' in crates/polars-plan/src/plans/options.rs:663) on a JoinType variant such as a cross join that carries no key columns; typically reached via programmatic construction or optimization passes that reassign join keys.
Common situations: Contributors modifying join planning code, adding a new JoinType variant, or optimizations that rewrite join keys on already-built join nodes. End users essentially never see this unless a higher-level API misroutes a join configuration into the planner.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- not implemented
- length to fit in `usize`
- offset to fit in `usize`
- Offset to fit in `usize`
- The external API has a non-utf8 as format
AI-assisted analysis of pola-rs/polars@68506541d2 (2026-08-28).
Data as JSON: /api/errors/a4a563439ccc31ef.
Report an issue: GitHub.