jdx/mise · error
timed out after {timeout:?}
Error message
timed out after {timeout:?} What it means
Raised by the bounded/isolated command reader (read_isolated in src/cmd/bounded.rs) when the spawned child does not finish before the configured timeout elapses. The child process and its process tree are killed first (end()), then a timeout error is returned. It guards mise against hanging on a stuck subprocess.
Source
Thrown at src/cmd/bounded.rs:49
// allocate twice what was asked before anyone objected.
let budget = AtomicUsize::new(limit);
let result = tokio::time::timeout(timeout, async {
tokio::try_join!(
child.wait(),
capture(stdout, &budget, limit),
capture(stderr, &budget, limit)
)
})
.await;
let (status, stdout, _stderr) = match result {
Ok(Ok(output)) => output,
Ok(Err(err)) => {
end(&mut child, tree).await;
return Err(err.into());
}
Err(_) => {
end(&mut child, tree).await;
bail!("timed out after {timeout:?}");
}
};
if !status.success() {
bail!("command exited with non-zero status: {status}");
}
Ok(String::from_utf8(stdout)?.trim_end().to_string())
}
}
/// How long reaping a killed command may take before it is left to the
/// operating system. A process that has been killed is normally gone at
/// once; one that is not is no reason to outlive the deadline.
const REAP: Duration = Duration::from_secs(1);
/// End the command and account for it, without waiting on a process that
/// may not be listening. Closing the tree kills the group, but the direct
/// child can be outside it — on Windows it may never have joined the job,
/// and on unix it can have left the group — and `kill_on_drop` cannot runView on GitHub (pinned to afd2eddd3a)
Solutions
- Increase the timeout value at the call site if the command is legitimately slow
- Fix the underlying command so it completes unattended (remove interactive prompts)
- Check network/proxy availability if the command fetches remote data
- Investigate the stuck process tree; the child is killed, so look at what it was waiting on
Example fix
// before read_isolated(&mut cmd, Duration::from_secs(5), &tree).await? // after read_isolated(&mut cmd, Duration::from_secs(60), &tree).await?
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the command can run unattended and quickly: smoke-test it first // e.g. time out manually before wiring it into mise timeout 10 <command> --version || echo "command may hang"
Try / catch
match read_isolated(&mut cmd, timeout, &tree).await {
Ok(out) => out,
Err(e) if e.to_string().starts_with("timed out after") => {
// retry once with a larger timeout or fall back to a cached value
retry_with_timeout(timeout * 4).await.unwrap_or_else(|_| cached_value())
}
Err(e) => return Err(e),
} Prevention
- Set realistic timeouts for commands that hit the network
- Never rely on interactive commands for isolated reads
- Cache previous successful output as a fallback
- Monitor for wedged processes if timeouts recur
When it happens
Trigger: Any call into read_isolated where the child command blocks (reads stdin, waits on network, deadlock) longer than the `timeout` duration passed to the function.
Common situations: A tool-version listing command hangs on a slow/unreachable network; a plugin script prompts for input while stdin is captured; a wedged daemon holds the child open.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- command output pipes did not close within {pipe_drain_timeou
- timed out after {timeout:?}
- ditto failed copying {} to {}
- brew-cask: failed to generate {} completions from {}: {}
- git command failed with {status}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/36aeb5227efd8c10.
Report an issue: GitHub.