pola-rs/polars · error
expected total ordering
Error message
expected total ordering
What it means
reorder_cmp uses PartialOrd::partial_cmp and unwraps with 'expected total ordering'; if partial_cmp returns None the type's comparison is not a total order (e.g. NaN floats) and it panics. Null handling is done after, so the panic fires for non-null values that cannot be ordered.
Solutions
- Sanitize data before sorting: replace NaN with null (fill_nan) or a sentinel so null handling takes over
- Use sort options that treat NaN explicitly, or drop/fillna NaN values first
- Verify custom element types implement a true total order (Ord, not just PartialOrd)
Example fix
// before
df.sort(["price"], SortMultipleOptions::default());
// after
let df = df.with_column(col("price").fill_nan(lit(f64::NAN).is_null())).unwrap(); // or fill_nan(lit(0.0))
df.sort(["price"], SortMultipleOptions::default()); Defensive patterns
Strategy: validation
Validate before calling
# Polars: remove non-orderable NaN before sorting s = df["price"] assert not s.drop_nulls().is_nan().any(), "NaN values break total ordering; use fill_nan or drop them"
Prevention
- fill_nan or drop NaN values before arg_sort/sort operations
- For custom element types, implement Ord (total order), not just PartialOrd
- Test multi-column sorts on data containing NaN and nulls
When it happens
Trigger: Sorting/ordering columns containing NaN or other values where partial_cmp yields None; calling arg_sort_multiple or any of its helpers (cmp_element_unchecked, cmp_at, etc.) on such data.
Common situations: Sorting float columns with NaN; user-defined or exotic types with inconsistent Ord; comparing mixed-type or corrupted data in multi-column sorts.
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
- activate dtype
- addition overflow: +
- can only use timedelta string language with…
- cannot coerce datatypes
- cannot convert negative slice into range
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/59ba477912b3e076.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-utils/src/sort.rs:119
{
fn cmp(&self, other: &Self) -> Ordering {
reorder_cmp(&self.0, &other.0, DESCENDING, NULLS_LAST)
}
}
/// Compare two values with support for sort direction and nulls position.
///
/// # Panics
///
/// Panics if `T::partial_cmp(lhs, rhs)` returns `None`.
#[inline]
pub fn reorder_cmp<T: PartialOrd + IsNull>(
lhs: &T,
rhs: &T,
descending: bool,
nulls_last: bool,
) -> Ordering {
match PartialOrd::partial_cmp(lhs, rhs).expect("expected total ordering") {
Ordering::Equal => Ordering::Equal,
_ if lhs.is_null() && nulls_last => Ordering::Greater,
_ if rhs.is_null() && nulls_last => Ordering::Less,
_ if lhs.is_null() => Ordering::Less,
_ if rhs.is_null() => Ordering::Greater,
ord if descending => ord.reverse(),
ord => ord,
}
}
View on GitHub (pinned to fe841f959e)