gleam-lang/gleam · error
Unable to start Tokio async runtime
Error message
Unable to start Tokio async runtime
What it means
`gleam add <pkg>` (owner.rs::add) creates a multi-thread Tokio runtime to drive reqwest HTTP calls against hex.pm, and Runtime::new() must succeed (expect("Unable to start Tokio async runtime")). Runtime creation fails when the process cannot allocate the runtime's worker threads or set up its I/O driver — i.e. resource exhaustion (thread/memory limits), not anything about the package being added. The panic occurs before any network request, so credentials are never even read.
Source
Thrown at compiler-cli/src/owner.rs:12
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2025 The Gleam contributors
use crate::{cli, http::HttpClient};
use gleam_core::{Result, hex};
pub fn add(
package: String,
new_owner_username_or_email: String,
level: hexpm::OwnerLevel,
) -> Result<()> {
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()?;
cli::print_adding_owner();
runtime.block_on(hex::add_owner(
&crate::hex::write_credentials(&credentials)?,
package,
new_owner_username_or_email,
level,
&hex_config,
&http,
))?;
cli::print_added_owner();
Ok(())
}View on GitHub (pinned to 7e623aa83d)
Solutions
- Raise the process/thread limits and retry: `ulimit -u 4096` (or raise nproc limits in limits.conf), and in docker use `--pids-limit 256` or remove it.
- Free memory pressure (stop parallel builds, add swap) so the runtime's worker stacks can be allocated, then retry the command.
- If you embed this code path, build a cheaper runtime instead: tokio::runtime::Builder::new_current_thread().enable_all().build() still satisfies reqwest here.
- Check `dmesg`/container events for OOM or cgroup pids-max denials to confirm the resource that ran out.
Example fix
# before: container with a very low pids limit docker run --pids-limit 16 my-gleam-ci gleam add gleam_http # panics: Unable to start Tokio async runtime # after: enough headroom for worker threads docker run --pids-limit 512 my-gleam-ci gleam add gleam_http
Defensive patterns
Strategy: retry
Validate before calling
# Check thread headroom before running gleam add in CI ulimit -u # soft nproc limit; raise if tiny (e.g. < 512) cat /sys/fs/cgroup/pids/current 2>/dev/null # container usage vs pids.max # if too low, raise limits first, then run: ulimit -u 4096 2>/dev/null; gleam add gleam_http
Prevention
- Give CI containers generous pids limits (docker --pids-limit 512+) when the job runs gleam/other Tokio tools.
- Avoid running gleam add concurrently with heavy parallel builds that consume the thread budget.
- Script the command to retry once after freeing resources, since nothing is mutated before the runtime starts.
When it happens
Trigger: Running `gleam add` inside a container with a tiny pids limit (docker --pids-limit), under a low `ulimit -u`/`ulimit -v`, in a cgroup near its memory ceiling so thread stacks can't be mapped, or in a seccomp sandbox that blocks epoll/clone for the I/O driver.
Common situations: Docker/Devcontainer/Podman defaults (pids-limit=10..100), shared CI runners during heavy parallel builds, gVisor/Firecracker microVMs with restricted syscalls, systems at their global thread limit from other tooling.
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/37e9925f14eee54a.
Report an issue: GitHub.