gleam-lang/gleam · error
Unable to start Tokio async runtime
Error message
Unable to start Tokio async runtime
What it means
publish.rs::main creates its Tokio runtime with expect("Unable to start Tokio async runtime") after listing files and asking 'Do you wish to publish this package?'. This is the same resource-exhaustion failure as other commands: the multi-thread runtime cannot spawn workers or register its I/O driver. The panic fires after confirmation but before hex::publish_package, so no package state changes on hex.pm.
Source
Thrown at compiler-cli/src/publish.rs:87
println!("\nGenerated files:");
for file in generated_files_added.iter().sorted() {
println!(" - {}", file.0);
}
}
println!("\nSource files:");
for file in src_files_added.iter().sorted() {
println!(" - {file}");
}
println!("\nName: {}", config.name);
println!("Version: {}", config.version);
let should_publish = i_am_sure || cli::confirm("\nDo you wish to publish this package?")?;
if !should_publish {
println!("Not publishing.");
return Ok(());
}
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
let http = HttpClient::new();
let hex_config = hexpm::Config::new();
let credentials = crate::hex::HexAuthentication::new(&runtime, &http, hex_config.clone())
.get_or_create_api_credentials()?;
let credentials = crate::hex::write_credentials(&credentials)?;
cli::print_publishing(&config.name, &config.version);
runtime.block_on(hex::publish_package(
package_tarball,
config.version.to_string(),
&config.name,
&credentials,
&hex_config,
replace,
&http,
))?;
cli::print_publishing_documentation();View on GitHub (pinned to 7e623aa83d)
Solutions
- Re-run publish with more headroom: raise the container pids limit and thread ulimits, or exec the publish step outside the sandbox.
- Relieve memory/thread pressure on the machine (wait for parallel jobs), then `gleam publish --yes` to skip the interactive prompt.
- For library users of this code, replace Runtime::new() with Builder::new_current_thread().enable_all().build().
- Confirm the limit in CI logs (`pids.max`, exit context) and bake a higher limit into the release job image.
Example fix
# before: release job constrained by default pids limit - run: gleam publish --yes # panics: Unable to start Tokio async runtime # after: publish step with adequate limits - run: gleam publish --yes # plus container config: pids_limit: 512 (compose) or --pids-limit=512 (docker)
Defensive patterns
Strategy: retry
Validate before calling
# Release pipeline preflight: enough pids and memory for a Tokio runtime
[ "$(cat /sys/fs/cgroup/pids/pids.max 2>/dev/null)" != "16" ] || (echo raise pids limit; exit 1)
avail_kb=$(awk '/MemAvailable/{print $2}' /proc/meminfo); [ "$avail_kb" -gt 262144 ] || exit 1
gleam publish --yes Prevention
- Configure release CI containers with pids_limit >= 512 and a couple of GiB memory.
- Don't overlap `gleam publish` with parallel compilation jobs on thread-starved runners.
- Because the panic happens before hex::publish_package, re-running publish after fixing limits is safe (no partial upload).
When it happens
Trigger: `gleam publish` in a CI container with low pids-limit, low ulimit -u/-v, heavy memory pressure, or a seccomp/gVisor sandbox blocking the syscalls Tokio needs — hitting exactly between the confirmation prompt and the upload.
Common situations: Release pipelines in Docker (default or small --pids-limit), self-hosted runners shared with many jobs, or gVisor/Firecracker CI sandboxes; the tag was pushed and CI failed at publish time.
Related errors
- Unable to start Tokio async runtime
- Unable to start Tokio async runtime
- Unable to start Tokio async runtime
- Unable to start Tokio async runtime
- joining_lsp_threads
AI-assisted analysis of gleam-lang/gleam@7e623aa83d (2026-08-17).
Data as JSON: /api/errors/65a1930a8a31a82a.
Report an issue: GitHub.