pola-rs/polars · critical
integer
Error message
integer
What it means
RuntimeManager::new reads POLARS_ASYNC_THREAD_COUNT (line 19) and POLARS_MAX_BLOCKING_THREAD_COUNT, calling parse::<usize>().expect("integer"). Any value that is not a bare unsigned integer - floats, negative numbers, whitespace, empty string - panics. The manager initializes lazily on first async use, so the panic surfaces far from the env var that caused it.
Source
Thrown at crates/polars-async/src/lib.rs:19
use std::sync::{Arc, LazyLock};
use polars_error::polars_warn;
use polars_utils::relaxed_cell::RelaxedCell;
use tokio::runtime::{Builder, Runtime};
use crate::executor::{THREAD_SPAWNED_BY_POLARS_EXECUTOR, is_scheduling_polars_executor_thread};
pub mod executor;
pub mod primitives;
pub struct RuntimeManager {
rt: Runtime,
}
impl RuntimeManager {
fn new() -> Self {
let n_threads = std::env::var("POLARS_ASYNC_THREAD_COUNT")
.map(|x| x.parse::<usize>().expect("integer"))
.unwrap_or(usize::min(polars_config::config().max_threads(), 32));
let max_blocking = std::env::var("POLARS_MAX_BLOCKING_THREAD_COUNT")
.map(|x| x.parse::<usize>().expect("integer"))
.unwrap_or(512);
if polars_config::config().verbose() {
eprintln!("async thread count: {n_threads}");
eprintln!("blocking thread count: {max_blocking}");
}
let max_total_threads = n_threads + max_blocking;
let warned = RelaxedCell::new_bool(false);
let tokio_thread_count_start = Arc::new(RelaxedCell::new_i64(0));
let tokio_thread_count_stop = tokio_thread_count_start.clone();
let rt = Builder::new_multi_thread()
.worker_threads(n_threads)View on GitHub (pinned to df599052da)
Solutions
- Fix the value to a plain decimal integer: export POLARS_ASYNC_THREAD_COUNT=8
- Or simply unset it - Polars then defaults to min(max_threads, 32)
- Audit sibling variable POLARS_MAX_BLOCKING_THREAD_COUNT, which fails identically
- Check for literal quotes, spaces, 'K'-suffixes, or negative signs in the env value
Example fix
# before export POLARS_ASYNC_THREAD_COUNT="8 " # trailing space -> parse fails # after export POLARS_ASYNC_THREAD_COUNT=8
Defensive patterns
Strategy: validation
Validate before calling
// Rust: verify before any async work
for var in ["POLARS_ASYNC_THREAD_COUNT", "POLARS_MAX_BLOCKING_THREAD_COUNT"] {
if let Ok(v) = std::env::var(var) {
assert!(v.parse::<usize>().is_ok(), "{var} must be a plain integer, got {v:?}");
}
}
# Shell: fail fast in entrypoints
[ -z "${POLARS_ASYNC_THREAD_COUNT:-}" ] || [[ "$POLARS_ASYNC_THREAD_COUNT" =~ ^[0-9]+$ ]] \
|| { echo "POLARS_ASYNC_THREAD_COUNT must be an integer" >&2; exit 1; } Prevention
- Set thread-count env vars to bare decimal integers or leave them unset
- Quote-check .env/docker-compose values for stray spaces and quotes
- Guard empty interpolations: :-${var:-} patterns can inject ''
- Validate both POLARS_ASYNC_THREAD_COUNT and POLARS_MAX_BLOCKING_THREAD_COUNT in container entrypoints
When it happens
Trigger: First use of Polars' async runtime (cloud reads, async globbing, async engine) with POLARS_ASYNC_THREAD_COUNT set to values like '4.0', ' 4', '-1', or '' (empty interpolation).
Common situations: .env / docker-compose entries with quotes or trailing whitespace; shell scripts interpolating unset variables to empty strings; copy-pasted configs expecting float thread counts; CI injecting stray values.
Related errors
- error initializing temporary directory: {e} consider explici
- not implemented
- not implemented
- not implemented
- horizontal_flatten not supported for data type {:?}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/9378a79e2fe50c6b.
Report an issue: GitHub.