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

  1. Unset POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD to use the 16,777,216 default
  2. Set it to a plain positive decimal integer, e.g. export POLARS_PARQUET_DECODE_TARGET_VALUES_PER_THREAD=16777216
  3. 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

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


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)