pola-rs/polars · error

invalid `POLARS_MAX_CACHED_METADATA_SCANS` value

Error message

invalid `POLARS_MAX_CACHED_METADATA_SCANS` value

What it means

POLARS_MAX_CACHED_METADATA_SCANS is read once (LazyLock) and parsed as usize; a value that is not a bare non-negative integer makes v.parse() fail and this expect panics inside the lazy initializer. Note the default is 8 and the literal 0 means 'unlimited'.

Source

Thrown at crates/polars-plan/src/plans/conversion/dsl_to_ir/scans.rs:614

    if source.is_cloud_url() {
        let path = source.as_path().unwrap();
        feature_gated!("cloud", {
            let mut reader =
                ParquetObjectStore::from_uri(path.clone(), cloud_options, None).await?;
            reader.num_rows_only().await
        })
    } else {
        let memslice = source.to_memslice()?;
        let mut cursor = Cursor::new(memslice);
        polars_parquet::parquet::read::read_num_rows(&mut cursor).map_err(Into::into)
    }
}

pub fn max_metadata_scan_cached() -> usize {
    static MAX_SCANS_METADATA_CACHED: LazyLock<usize> = LazyLock::new(|| {
        let value = std::env::var("POLARS_MAX_CACHED_METADATA_SCANS").map_or(8, |v| {
            v.parse::<usize>()
                .expect("invalid `POLARS_MAX_CACHED_METADATA_SCANS` value")
        });

        if value == 0 {
            return usize::MAX;
        }

        if polars_config::config().verbose() {
            eprintln!("parquet max cached metadata scans: {value}")
        };

        value
    });
    *MAX_SCANS_METADATA_CACHED
}

// TODO! return metadata arced
#[cfg(feature = "ipc")]
pub(super) async fn ipc_file_info(

View on GitHub (pinned to df599052da)

Solutions

  1. Set a plain non-negative integer: export POLARS_MAX_CACHED_METADATA_SCANS=8
  2. Unset the variable to accept the default (8)
  3. Set it to 0 only if you intentionally want unlimited metadata scans cached
  4. Check for stray whitespace/quotes in the environment definition (docker ENV, .env files)

Example fix

# before
export POLARS_MAX_CACHED_METADATA_SCANS="8 scans"  # panic on first parquet scan

# after
export POLARS_MAX_CACHED_METADATA_SCANS=8
Defensive patterns

Strategy: validation

Validate before calling

# startup sanity check before polars touches the env
import os
v = os.environ.get("POLARS_MAX_CACHED_METADATA_SCANS")
if v is not None and not v.isdigit():
    raise ValueError(f"POLARS_MAX_CACHED_METADATA_SCANS must be a non-negative integer, got {v!r}")

Prevention

When it happens

Trigger: Setting the env var to a non-integer (e.g. 'eight', '8 ', '0x8') or a negative number, then performing any parquet scan/metadata-cached operation that first touches max_metadata_scan_cached().

Common situations: Deployment configs and CI env files with typos; values copied with units ('16 scans'); empty string also fails to parse; underscores like '1_000' are rejected by usize::from_str.

Related errors


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