aaif-goose/goose · critical
Failed to spawn goose-cli main thread: {}
Error message
Failed to spawn goose-cli main thread: {} What it means
goose-cli's main() spawns a dedicated 8 MiB-stack thread that builds the Tokio runtime and runs the CLI (crates/goose-cli/src/main.rs:41-49). std::thread::Builder::spawn returns io::Error when the OS refuses to create the thread, and that error is wrapped into this anyhow error. This is a host-level failure, not a goose logic bug: the process could not even start its main worker thread.
Source
Thrown at crates/goose-cli/src/main.rs:48
result
}
fn main() -> Result<()> {
#[cfg(windows)]
enable_windows_vt_processing();
let handle = std::thread::Builder::new()
.name("goose-cli-main".to_string())
.stack_size(8 * 1024 * 1024)
.spawn(|| {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to build Tokio runtime");
runtime.block_on(run())
})
.map_err(|e| anyhow::anyhow!("Failed to spawn goose-cli main thread: {}", e))?;
handle
.join()
.map_err(|_| anyhow::anyhow!("goose-cli main thread panicked"))?
}
View on GitHub (pinned to 3810898a74)
Solutions
- Free system resources (reduce running threads/processes) and retry; check `ulimit -u` and raise the max user processes limit
- Give the container/host more memory, or lower the stack_size requirement if you control the code
- Check dmesg/container logs for OOM or seccomp denials if the spawn keeps failing
Defensive patterns
Strategy: validation
Validate before calling
// Before spawning heavy threads, sanity-check availability
fn can_spawn_thread() -> bool {
std::thread::Builder::new()
.stack_size(1 << 20)
.spawn(|| {})
.map(|h| h.join().is_ok())
.unwrap_or(false)
} Prevention
- Run goose with headroom on thread/memory limits (check `ulimit -u`, cgroup memory ceiling)
- Avoid launching goose from parents near their process/thread cap
- In containers, size memory limits above the ~8 MiB stack plus runtime working set
When it happens
Trigger: Thread creation fails with EAGAIN: per-process thread limit reached (ulimit -u), RLIMIT_STACK/memory limits preventing the 8 MiB stack allocation, cgroup/container memory exhaustion, or a sandboxed environment denying thread creation.
Common situations: Running goose in a constrained container/cgroup near its memory ceiling, a host at its nproc/thread limit under heavy load, or overly strict sandboxing (seccomp/LSM) of the CLI.
Related errors
- goose-cli main thread panicked
- Provider '{}' has dynamic_models: false but no static models
- missing required key {}: {}
- Anthropic provider does not support non-streaming mode. All
- ACP URL is not available
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/f1d2d11e486013e8.
Report an issue: GitHub.