gleam-lang/gleam · error
Unable to start Tokio async runtime
Error message
Unable to start Tokio async runtime
What it means
Panic from `tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime")` in compiler-cli/src/hex.rs retire(). Tokio failed to create its async runtime, almost always because the process cannot spawn worker threads or install the reactor (resource exhaustion, or a runtime already being initialized in a context that forbids it). The CLI cannot perform any async Hex API call without it.
Solutions
- Check and raise process/thread limits (ulimit -u, container pids/memory limits) on the machine running the CLI.
- Free memory or reduce system load; Runtime::new fails when the OS cannot allocate resources.
- If embedding gleam, call retire from a non-async context or refactor to reuse an existing runtime instead of creating a new one.
- Replace the expect with graceful error handling that prints guidance instead of panicking.
Example fix
// before
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
// after
let runtime = tokio::runtime::Runtime::new()
.map_err(|e| anyhow::anyhow!("Unable to start Tokio async runtime: {e}"))?; Defensive patterns
Strategy: fallback
Validate before calling
// Check resources before running the CLI: // ulimit -u; cat /sys/fs/cgroup/pids.max; free -m
Try / catch
// std::panic::catch_unwind around the sync hex call when embedding: let result = std::panic::catch_unwind(|| gleam_hex::retire(pkg, ver, reason, msg));
Prevention
- Run CLI commands with adequate thread/memory limits.
- Avoid calling sync hex functions from inside another Tokio runtime.
- Surface runtime-creation errors as Result instead of expect in library code.
When it happens
Trigger: Calling gleam's hex retire when Runtime::new() returns Err: thread spawn failure (ulimit -u exhausted, cgroup pids limit, low memory) or running inside an environment where tokio cannot initialize the I/O driver.
Common situations: Running the gleam CLI in restricted containers/CI with very low limits; embedding gleam inside another Rust binary that already owns a Tokio runtime and calls this sync function from a runtime thread in ways that exhaust resources.
Related errors
AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14).
Data as JSON: /api/errors/221e15bb8a965c8a.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-cli/src/hex.rs:39
match credentials {
hexpm::Credentials::ApiKey(key) => Ok(hexpm::WriteActionCredentials::ApiKey(key.clone())),
hexpm::Credentials::OAuthAccessToken(token) => {
let one_time_password = cli::ask("Enter your two-factor authentication code")?.into();
Ok(hexpm::WriteActionCredentials::OAuthAccessToken {
access_token: token.clone(),
one_time_password,
})
}
}
}
pub fn retire(
package: String,
version: String,
reason: RetirementReason,
message: Option<String>,
) -> Result<()> {
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
let config = hexpm::Config::new();
let http = HttpClient::new();
let credentials =
HexAuthentication::new(&runtime, &http, config.clone()).get_or_create_api_credentials()?;
runtime.block_on(hex::retire_release(
&package,
&version,
reason,
message.as_deref(),
&write_credentials(&credentials)?,
&config,
&http,
))?;
cli::print_retired(&package, &version);
Ok(())
}
View on GitHub (pinned to 15b07c7830)