{"record":{"id":"b9def59483564127","repo":"pola-rs/polars","slug":"invalid-polars-max-cached-metadata-scans-value","errorCode":null,"errorMessage":"invalid `POLARS_MAX_CACHED_METADATA_SCANS` value","messagePattern":"invalid `POLARS_MAX_CACHED_METADATA_SCANS` value","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-plan/src/plans/conversion/dsl_to_ir/scans.rs","lineNumber":614,"sourceCode":"    if source.is_cloud_url() {\n        let path = source.as_path().unwrap();\n        feature_gated!(\"cloud\", {\n            let mut reader =\n                ParquetObjectStore::from_uri(path.clone(), cloud_options, None).await?;\n            reader.num_rows_only().await\n        })\n    } else {\n        let memslice = source.to_memslice()?;\n        let mut cursor = Cursor::new(memslice);\n        polars_parquet::parquet::read::read_num_rows(&mut cursor).map_err(Into::into)\n    }\n}\n\npub fn max_metadata_scan_cached() -> usize {\n    static MAX_SCANS_METADATA_CACHED: LazyLock<usize> = LazyLock::new(|| {\n        let value = std::env::var(\"POLARS_MAX_CACHED_METADATA_SCANS\").map_or(8, |v| {\n            v.parse::<usize>()\n                .expect(\"invalid `POLARS_MAX_CACHED_METADATA_SCANS` value\")\n        });\n\n        if value == 0 {\n            return usize::MAX;\n        }\n\n        if polars_config::config().verbose() {\n            eprintln!(\"parquet max cached metadata scans: {value}\")\n        };\n\n        value\n    });\n    *MAX_SCANS_METADATA_CACHED\n}\n\n// TODO! return metadata arced\n#[cfg(feature = \"ipc\")]\npub(super) async fn ipc_file_info(","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-plan/src/plans/conversion/dsl_to_ir/scans.rs#L596-L632","documentation":"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'.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Set a plain non-negative integer: export POLARS_MAX_CACHED_METADATA_SCANS=8","Unset the variable to accept the default (8)","Set it to 0 only if you intentionally want unlimited metadata scans cached","Check for stray whitespace/quotes in the environment definition (docker ENV, .env files)"],"exampleFix":"# before\nexport POLARS_MAX_CACHED_METADATA_SCANS=\"8 scans\"  # panic on first parquet scan\n\n# after\nexport POLARS_MAX_CACHED_METADATA_SCANS=8","handlingStrategy":"validation","validationCode":"# startup sanity check before polars touches the env\nimport os\nv = os.environ.get(\"POLARS_MAX_CACHED_METADATA_SCANS\")\nif v is not None and not v.isdigit():\n    raise ValueError(f\"POLARS_MAX_CACHED_METADATA_SCANS must be a non-negative integer, got {v!r}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate all POLARS_* tuning vars in one bootstrap script","Never add units or separators to numeric env values","Document 0 = unlimited in the runbook"],"tags":["environment-variable","configuration","parquet","panic","rust"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}