pola-rs/polars · error

scalar ordering for mixed dtypes

Error message

scalar ordering for mixed dtypes {self:?} and {other:?} is not supported

What it means

AnyValue::partial_cmp reached its catch-all arm: two scalars of different or unorderable dtypes were compared, and no comparison rule exists. This is a dtype-mismatch at the scalar comparison level — Polars refuses to impose an arbitrary order.

Solutions

  1. Cast both sides to a common dtype before comparing: pl.col('a').cast(pl.Utf8) == pl.col('b')
  2. Inspect dtypes first (df.schema) and fix parsing/ingestion so columns share one dtype
  3. Use strict=False casts or explicit fill for nulls where types differ
  4. For sorts, ensure all sort keys share the same dtype

Example fix

// before
df.filter(pl.col('a') == pl.col('b'))  # a: Int64, b: Utf8 -> panics
// after
df.filter(pl.col('a').cast(pl.Utf8) == pl.col('b'))
Defensive patterns

Strategy: validation

Validate before calling

schema = df.collect_schema()
assert schema['a'].base_type() == schema['b'].base_type(), f"dtype mismatch: {schema['a']} vs {schema['b']}"

Type guard

def same_dtype(a: pl.DataType, b: pl.DataType) -> bool:
    return a == b

Try / catch

try:
    out = df.filter(pl.col('a') == pl.col('b'))
except Exception as e:
    if 'scalar ordering' in str(e):
        out = df.filter(pl.col('a').cast(pl.Utf8, strict=False) == pl.col('b'))
    else:
        raise

Prevention

When it happens

Trigger: Comparing AnyValues of different dtypes (e.g. Int64 vs Utf8, Decimal vs Float) through APIs built on partial_cmp, or through feature-unusual pairings (e.g. Binary vs Int, Time vs Datetime) in sort/comparison contexts.

Common situations: Mixed-type columns produced by concat, melt/pivot, or CSV parsing with inconsistent types; sort_keys of differing dtypes; after schema changes the compared columns no longer match.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/d23be6609da572ab. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-core/src/datatypes/any_value.rs:1483

            (Array(..), Array(..)) => {
                unimplemented!("ordering for Array dtype is not supported")
            },
            #[cfg(feature = "object")]
            (Object(_), Object(_)) => {
                unimplemented!("ordering for Object dtype is not supported")
            },
            #[cfg(feature = "dtype-struct")]
            (StructOwned(_), StructOwned(_))
            | (StructOwned(_), Struct(..))
            | (Struct(..), StructOwned(_))
            | (Struct(..), Struct(..)) => {
                unimplemented!("ordering for Struct dtype is not supported")
            },
            #[cfg(feature = "dtype-decimal")]
            (Decimal(lv, _lp, ls), Decimal(rv, _rp, rs)) => Some(dec128_cmp(*lv, *ls, *rv, *rs)),

            (_, _) => {
                unimplemented!(
                    "scalar ordering for mixed dtypes {self:?} and {other:?} is not supported"
                )
            },
        }
    }
}

impl TotalEq for AnyValue<'_> {
    #[inline]
    fn tot_eq(&self, other: &Self) -> bool {
        self.eq_missing(other, true)
    }
}

#[cfg(feature = "dtype-struct")]
fn struct_to_avs_static(idx: usize, arr: &StructArray, fields: &[Field]) -> Vec<AnyValue<'static>> {
    assert!(idx < arr.len());

View on GitHub (pinned to fe841f959e)