{"record":{"id":"25631fc5ad0d959c","repo":"dbt-labs/dbt-core","slug":"failed-to-spawn-worker-thread","errorCode":null,"errorMessage":"failed to spawn worker thread","messagePattern":"failed to spawn worker thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-main/src/dbt_lib.rs","lineNumber":2987,"sourceCode":"                            Ok(record_batch) => {\n                                shared_results_clone.lock().unwrap().push(record_batch);\n                            }\n                            Err(e) => {\n                                let msg = format!(\"[Non-critical] Issue processing catalog for schema '{database}.{schema}': {e}\");\n                                emit_info_log_message(&msg);\n                                shared_errors_clone.lock().unwrap().push(msg);\n                            }\n                        },\n                        Err(e) => {\n                            let msg = format!(\"[Non-critical] Issue fetching catalog for schema '{database}.{schema}': {e}\");\n                            emit_info_log_message(&msg);\n                            shared_errors_clone.lock().unwrap().push(msg);\n                        }\n                    }\n                }\n                Ok(())\n            })\n            .expect(\"failed to spawn worker thread\");\n        handles.push(handle);\n    }\n\n    // Do this so that handles are not abandoned immediately while we poll\n    let _handles = handles;\n\n    // Do not await workers directly as they may lock due to ADBC issues\n    loop {\n        tokio::time::sleep(POLL_INTERVAL).await;\n\n        let tracker_snapshot = progress_tracker.lock().unwrap().clone();\n\n        // All workers finished normally\n        if tracker_snapshot.is_empty() {\n            emit_info_log_message(\"Fetched full catalog.json results\");\n            break;\n        }\n","sourceCodeStart":2969,"sourceCodeEnd":3005,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-main/src/dbt_lib.rs#L2969-L3005","documentation":"`fetch_catalog_data` spawns rayon/worker threads to query catalog metadata in parallel and panics if `std::thread::Builder` (or equivalent spawn) fails. Thread spawn fails essentially only on OS resource exhaustion — inability to allocate a stack or hit the process/thread limit.","triggerScenarios":"`try_fetch_catalog` → `write_catalog_json` → `fetch_catalog_data` calls `.spawn()` with a large configured stack size (`thread_stack_size`) on a memory-constrained machine, or the process hits the OS thread/ulimit cap (ulimit -u, cgroup pids.max, containers with low thread limits).","commonSituations":"Running dbt docs generate in constrained Docker/K8s containers; large `DBT_*` stack-size env settings multiplying memory per worker; hitting `nproc`/pid limits with many catalog batches.","solutions":["Check `ulimit -u` and container pids/cgroup limits and raise them","Reduce memory pressure or the per-thread stack size (FS_DEFAULT_STACK_SIZE-derived setting)","Lower catalog query concurrency/batch thread count","Retry on a larger machine / rerun after other runaway processes exit"],"exampleFix":"// before\nlet handle = thread::Builder::new().stack_size(...).spawn(...).expect(\"failed to spawn worker thread\");\n// after\nlet handle = thread::Builder::new().stack_size(...).spawn(...)\n    .map_err(|e| ErrFatal.load_error(format!(\"failed to spawn catalog worker thread: {e}\")))?;","handlingStrategy":"retry","validationCode":"// pre-check thread headroom\nlet nproc = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1);\nif ulimit_u() < nproc * 2 { eprintln!(\"thread limit too low for catalog workers\"); }","typeGuard":null,"tryCatchPattern":"match thread::Builder::new().stack_size(sz).spawn(work) {\n    Ok(h) => handles.push(h),\n    Err(e) => errors.push(format!(\"catalog worker spawn failed: {e}\")),\n}","preventionTips":["Raise ulimit -u and container pids limits","Avoid oversized per-thread stack-size settings","Run docs generate on a machine with adequate memory","Lower catalog fetch concurrency in constrained environments"],"tags":["threads","resource-exhaustion","os-limits"],"backgroundTag":"resource-exhaustion","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}