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
- Keep integer literals within i64 range (−9223372036854775808..=9223372036854775807)
- Pass the value as a float or a string plus an explicit cast if precision permits
- Use a polars build with the dtype-i128 feature enabled (custom Rust build with features = ["dtype-i128"])
- 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
- Bound user-supplied ints before pl.lit
- Build with features=["dtype-i128"] if >63-bit ints are required
- Store oversized ids as strings or UInt128/Decimal columns, not literals
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
- not implemented
- no read method found
- should be hashable
- python function failed
- python function should return List[str]
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/e199d1ab7e2924f1.
Report an issue: GitHub.