pola-rs/polars · error
integer
Error message
integer
What it means
Polars panics with the bare message 'integer' when POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD is set but not parseable as a usize. This variable controls the target number of decoded values per thread during Parquet decoding, defaulting to 16,777,216 (16 Mi values). The expect('integer') panic occurs in begin_read of the Parquet source.
Solutions
- Unset POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD to use the 16,777,216 default
- Set it to a plain positive decimal integer, e.g. export POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD=16777216
- Remove thousands separators, decimals, and surrounding whitespace/quotes from the value
Example fix
// before export POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD=16,777,216 // after export POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD=16777216
Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate before scanning
if let Ok(v) = std::env::var("POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD") {
assert!(v.parse::<usize>().is_ok(), "POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD must be a usize integer, got: {v}");
} Type guard
fn valid_target_values(v: &str) -> bool { v.parse::<usize>().is_ok() } Prevention
- Avoid thousands separators and decimal points in the value
- Leave unset for the 16,777,216 default
- Validate numeric POLARS_* vars once at process startup
When it happens
Trigger: Setting POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD to a non-integer string ('16.5', 'auto', empty string), a negative number, or a value exceeding usize::MAX, then scanning a Parquet file with the streaming engine.
Common situations: Users copy values with thousands separators ('16,777,216') or float formatting; dotenv tooling injects 'null'/'undefined' strings from scripting languages.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- invalid value for POLARS_ROW_GROUP_PREFETCH_KBYTES_BUDGET
- invalid value for POLARS_ROW_GROUP_PREFETCH_SIZE
- Invalid `POLARS_PQ_PREFILTERED_MASK` value
- invalid value for POLARS_MEMORY_PREFETCH
- invalid value for POLARS_NDJSON_CHUNK_SIZE
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/752b0a29b7bce462.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-stream/src/nodes/io_sources/parquet/mod.rs:380
});
return Ok((rx, handle));
}
// Prepare parameters for dispatch
let projected_arrow_fields = projected_arrow_fields()?.clone();
let memory_prefetch_func = get_memory_prefetch_func(verbose);
let row_group_prefetch_size = self
.row_group_prefetch_sync
.pipeline_budget
.count_limit()
.min(file_metadata.row_groups.len())
.max(1);
// This can be set to 1 to force column-per-thread parallelism, e.g. for bug reproduction.
let target_values_per_thread =
std::env::var("POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD")
.map(|x| x.parse::<usize>().expect("integer").max(1))
.unwrap_or(16_777_216);
let is_full_projection = projected_arrow_fields.len() == file_schema.len();
let (output_recv, handle) = ParquetReadImpl {
projected_arrow_fields,
is_full_projection,
predicate,
// TODO: Refactor to avoid full clone
options: Arc::unwrap_or_clone(self.config.clone()),
byte_source,
normalized_pre_slice: normalized_pre_slice.map(|x| match x {
Slice::Positive { offset, len } => (offset, len),
Slice::Negative { .. } => unreachable!(),
}),
metadata: file_metadata,
config: io_sources::parquet::Config {
num_pipelines,View on GitHub (pinned to fe841f959e)