pola-rs/polars · error

activate dtype-i128 feature

Error message

activate dtype-i128 feature

What it means

DynLiteralValue::Int stores the integer literal as i128. In builds without the dtype-i128 feature, try_materialize_to_dtype narrows it to i64 via try_into(); when the literal falls outside i64 range the conversion fails and this expect panics, telling you to build with dtype-i128 enabled.

Source

Thrown at crates/polars-plan/src/plans/lit.rs:173

            DataType::Array(_, size) => AnyValue::Array(s, *size),
            _ => unreachable!(),
        };

        Ok(Scalar::new(dtype.clone(), value))
    }
}

impl DynLiteralValue {
    pub fn try_materialize_to_dtype(
        self,
        dtype: &DataType,
        options: CastOptions,
    ) -> PolarsResult<Scalar> {
        match self {
            DynLiteralValue::Str(s) => Ok(Scalar::from(s).cast_with_options(dtype, options)?),
            DynLiteralValue::Int(i) => {
                #[cfg(not(feature = "dtype-i128"))]
                let i: i64 = i.try_into().expect("activate dtype-i128 feature");

                Ok(Scalar::from(i).cast_with_options(dtype, options)?)
            },
            DynLiteralValue::Float(f) => Ok(Scalar::from(f).cast_with_options(dtype, options)?),
            DynLiteralValue::List(dyn_list_value) => {
                dyn_list_value.try_materialize_to_dtype(dtype, options)
            },
        }
    }
}

impl RangeLiteralValue {
    pub fn try_materialize_to_series(self, dtype: &DataType) -> PolarsResult<Series> {
        fn handle_range_oob(range: &RangeLiteralValue, to_dtype: &DataType) -> PolarsResult<()> {
            polars_bail!(
                InvalidOperation:
                "conversion from `{}` to `{to_dtype}` failed for range({}, {})",
                range.dtype, range.low, range.high,

View on GitHub (pinned to df599052da)

Solutions

  1. Keep integer literals within i64 range (−9223372036854775808..=9223372036854775807)
  2. Pass the value as a float or a string plus an explicit cast if precision permits
  3. Use a polars build with the dtype-i128 feature enabled (custom Rust build with features = ["dtype-i128"])
  4. Materialize large values into a Series of a wide dtype instead of a literal expression

Example fix

# before
lf.filter(pl.col("id") == pl.lit(2**70))  # panic: activate dtype-i128 feature

# after (no i128 build): compare as float or string-cast
lf.filter(pl.col("id").cast(pl.Float64) == float(2**70))
# or build polars with features = ["dtype-i128"] and keep pl.lit(2**70)
Defensive patterns

Strategy: validation

Validate before calling

# Python: guard literal range before building expressions
I64_MIN, I64_MAX = -(2**63), 2**63 - 1
def safe_lit(v: int):
    assert I64_MIN <= v <= I64_MAX or float(v) == v, f"literal {v} exceeds i64; enable dtype-i128 or cast"
    return pl.lit(v)

Type guard

def fits_i64(v: int) -> bool:
    return -(2**63) <= v <= 2**63 - 1

Prevention

When it happens

Trigger: Passing a Python int literal beyond ±2^63 (e.g. pl.lit(2**70), or a huge constant in a lazy expression) in a polars build compiled without the dtype-i128 feature; triggers when the literal is materialized to a dtype during plan conversion/execution.

Common situations: Default pip wheels that do not enable dtype-i128; code ported from Python's arbitrary-precision ints (UUIDs as ints, snowflake IDs beyond 63 bits, cryptographic values); upgrading polars where large ints previously errored differently.

Related errors


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