xai-org/grok-build · error
spawn mermaid-render thread
Error message
spawn mermaid-render thread
What it means
`spawn_worker` spawns the dedicated mermaid-render thread and panics with 'spawn mermaid-render thread' if `std::thread::Builder::spawn` fails. The worker thread renders mermaid diagrams to PNG off the UI thread, so without it rendering cannot proceed at all.
Source
Thrown at crates/codegen/xai-grok-pager/src/app/mermaid_worker.rs:245
if writes_since_sweep >= SWEEP_EVERY_N_WRITES {
writes_since_sweep = 0;
if let Some(dir) = job.out_path.parent() {
// Off the draw path (worker thread); keeps the session's mermaid/ dir bounded within a session
sweep_session_cache(dir, SESSION_DISK_CAP_BYTES);
}
}
}
let result = MermaidResult {
key: job.key,
outcome,
};
if result_tx.send(result).is_err() {
return; // Receiver dropped; the view is gone.
}
}
}
})
.expect("spawn mermaid-render thread");
(job_tx, result_rx)
}
/// Coalesce `first` plus every job already queued on `rx` into a per-[`MermaidCacheKey`] map where the latest job for each key wins.
/// `IndexMap` keeps FIFO order across distinct keys, so independent diagrams still render in order.
fn drain_coalesced(
first: MermaidJob,
rx: &Receiver<MermaidJob>,
) -> IndexMap<MermaidCacheKey, MermaidJob> {
let mut pending: IndexMap<MermaidCacheKey, MermaidJob> = IndexMap::new();
pending.insert(first.key.clone(), first);
while let Ok(job) = rx.try_recv() {
pending.insert(job.key.clone(), job);
}
pending
}
View on GitHub (pinned to bc7f02eddd)
Solutions
- Check and raise thread limits: `ulimit -u`, container `pids.max` cgroup setting.
- Free memory or reduce the configured worker stack size so allocation succeeds.
- Check for thread leaks elsewhere in the process (join or terminate long-lived workers).
- Propagate the spawn error to the caller and degrade gracefully (render inline or report mermaid unavailable).
Example fix
// before
.expect("spawn mermaid-render thread");
// after
.map_err(|e| MermaidError::WorkerSpawn(e.to_string()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// preflight thread-creation capability
match std::thread::Builder::new().stack_size(64 * 1024).spawn(|| {}) {
Ok(h) => { h.join().ok(); }
Err(e) => eprintln!("thread limits exhausted: {e}"),
} Try / catch
match thread::Builder::new().name("mermaid-render").spawn(worker_loop) {
Ok(handle) => handle,
Err(e) => return Err(MermaidError::WorkerSpawn(e.to_string())),
} Prevention
- Raise ulimit -u / container pids.max in deployment configs
- Watch for thread leaks; join or reap finished worker threads
- Keep worker stack size modest to survive memory-constrained hosts
When it happens
Trigger: `std::thread::Builder::spawn` returning Err — the OS refused to create the thread, almost always due to resource limits.
Common situations: Hitting the process/thread limit (ulimit -u, cgroup pids.max); insufficient stack memory to reserve the worker stack under memory pressure; running inside a restricted sandbox/container with thread creation blocked.
Related errors
- failed to spawn acp-stdin reader thread
- just created
- Task panicked: {}
- failed to build shared blocking HTTP client
- Failed to load theme
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/e21933f787dd98f9.
Report an issue: GitHub.