{"record":{"id":"8b40ba6595cbbc00","repo":"EpicGames/lore","slug":"could-not-get-available-parallelism","errorCode":null,"errorMessage":"could not get available parallelism","messagePattern":"could not get available parallelism","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"lore-revision/src/store/seeder.rs","lineNumber":121,"sourceCode":"    let needed = max_size.saturating_sub(size + margin);\n\n    lore_info!(\"Current store size is {size}, {needed} bytes needed\");\n\n    if needed == 0 {\n        lore_info!(\"Store is already at desired capacity\");\n        return Ok(());\n    }\n\n    let fragment_count = needed / FRAGMENT_SIZE_THRESHOLD;\n\n    let in_flight = Arc::new(AtomicUsize::new(0));\n    let (tx, mut rx) = tokio::sync::mpsc::channel::<Bytes>(buffer_size);\n\n    // We don't expect this to ever fail in any realistic scenario where we'd be running seeding. If\n    // it does, I'd rather we panic so we can investigate rather than run at lower than expected\n    // concurrency.\n    let task_count = std::thread::available_parallelism()\n        .expect(\"could not get available parallelism\")\n        .get();\n\n    let per_task_count = fragment_count / task_count;\n\n    // Generation runs on dedicated threads rather than the runtime's pools: filling a buffer with\n    // random bytes has nothing to await, and a capacity tool wants the whole machine rather than a\n    // share of the process thread budget. Writes run on the runtime, bounded separately below, and\n    // the channel between the two is what tunes disk utilization.\n\n    lore_info!(\"Spawning {task_count} threads to generate payloads\");\n    for index in 0..task_count {\n        let tx = tx.clone();\n        let in_flight = in_flight.clone();\n\n        std::thread::Builder::new()\n            .name(format!(\"lore-seed-{index}\"))\n            .spawn(move || {\n                let mut rng = rand::rng();","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-revision/src/store/seeder.rs#L103-L139","documentation":"`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`.","triggerScenarios":"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.","commonSituations":"Hardened containers (gVisor/Firecracker-like sandboxes), restricted CI runners, embedded or unusual targets, or fuzzing/VM images with crippled /proc or sysconf.","solutions":["Run the seeding workload on a normal host OS/sandbox where `std::thread::available_parallelism()` succeeds (test with a tiny Rust program first).","Wrap the call in `std::panic::catch_unwind` if you must tolerate such environments.","Patch/override to fall back to a fixed task count (e.g. 1) when `available_parallelism()` errors."],"exampleFix":"// before\nlet task_count = std::thread::available_parallelism()\n    .expect(\"could not get available parallelism\")\n    .get();\n\n// after\nlet task_count = std::thread::available_parallelism()\n    .map(|n| n.get())\n    .unwrap_or(1);","handlingStrategy":"validation","validationCode":"// Probe before calling seed_local_store:\nmatch std::thread::available_parallelism() {\n    Ok(n) => println!(\"parallelism ok: {}\", n.get()),\n    Err(e) => eprintln!(\"environment cannot report parallelism: {e}\"),\n}","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| {\n    seed_local_store(args)\n});\nif result.is_err() {\n    eprintln!(\"seeding panicked (parallelism unavailable?)\");\n}","preventionTips":["Verify `std::thread::available_parallelism()` works in your deployment sandbox before shipping.","Avoid hardened sandboxes/seccomp profiles that block CPU-count syscalls for this workload.","Prefer a build that falls back to a fixed task count instead of panicking when parallelism is unavailable."],"tags":["rust","panic","parallelism"],"backgroundTag":"unsupported-platform","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}