EpicGames/lore · critical

could not get available parallelism

Error message

could not get available parallelism

What it means

`do_seed_local_store` calls `std::thread::available_parallelism().expect(...)` to size its worker pool; if the OS cannot report the available parallelism, the `.expect` panics the task rather than degrading to lower concurrency (a deliberate choice per the in-code comment). Callers of `seed_local_store` therefore see a panic, not an `Err`.

Solutions

  1. Run the seeding workload on a normal host OS/sandbox where `std::thread::available_parallelism()` succeeds (test with a tiny Rust program first).
  2. Wrap the call in `std::panic::catch_unwind` if you must tolerate such environments.
  3. Patch/override to fall back to a fixed task count (e.g. 1) when `available_parallelism()` errors.

Example fix

// before
let task_count = std::thread::available_parallelism()
    .expect("could not get available parallelism")
    .get();

// after
let task_count = std::thread::available_parallelism()
    .map(|n| n.get())
    .unwrap_or(1);
Defensive patterns

Strategy: validation

Validate before calling

// Probe before calling seed_local_store:
match std::thread::available_parallelism() {
    Ok(n) => println!("parallelism ok: {}", n.get()),
    Err(e) => eprintln!("environment cannot report parallelism: {e}"),
}

Try / catch

let result = std::panic::catch_unwind(|| {
    seed_local_store(args)
});
if result.is_err() {
    eprintln!("seeding panicked (parallelism unavailable?)");
}

Prevention

When it happens

Trigger: Calling `seed_local_store` in an environment where `available_parallelism()` returns an error — e.g. restricted sandboxes/seccomp profiles that block the syscalls it uses, unusual cgroup/container setups, or exotic/unusual platforms.

Common situations: Hardened containers (gVisor/Firecracker-like sandboxes), restricted CI runners, embedded or unusual targets, or fuzzing/VM images with crippled /proc or sysconf.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/8b40ba6595cbbc00. Report an issue: GitHub.

Appendix: source

Thrown at lore-revision/src/store/seeder.rs:121

    let needed = max_size.saturating_sub(size + margin);

    lore_info!("Current store size is {size}, {needed} bytes needed");

    if needed == 0 {
        lore_info!("Store is already at desired capacity");
        return Ok(());
    }

    let fragment_count = needed / FRAGMENT_SIZE_THRESHOLD;

    let in_flight = Arc::new(AtomicUsize::new(0));
    let (tx, mut rx) = tokio::sync::mpsc::channel::<Bytes>(buffer_size);

    // We don't expect this to ever fail in any realistic scenario where we'd be running seeding. If
    // it does, I'd rather we panic so we can investigate rather than run at lower than expected
    // concurrency.
    let task_count = std::thread::available_parallelism()
        .expect("could not get available parallelism")
        .get();

    let per_task_count = fragment_count / task_count;

    // Generation runs on dedicated threads rather than the runtime's pools: filling a buffer with
    // random bytes has nothing to await, and a capacity tool wants the whole machine rather than a
    // share of the process thread budget. Writes run on the runtime, bounded separately below, and
    // the channel between the two is what tunes disk utilization.

    lore_info!("Spawning {task_count} threads to generate payloads");
    for index in 0..task_count {
        let tx = tx.clone();
        let in_flight = in_flight.clone();

        std::thread::Builder::new()
            .name(format!("lore-seed-{index}"))
            .spawn(move || {
                let mut rng = rand::rng();

View on GitHub (pinned to 074eb0b0d1)