jdx/mise · error

timed out after

Error message

timed out after {timeout:?}

What it means

execute_hashes_async_with_drain_timeout completed the command but its exit status was non-zero and the TimeoutGuard reports the configured timeout elapsed, so the command was terminated by the timeout rather than failing on its own. The message includes how long it waited (timeout:?). This distinguishes a timeout kill from an ordinary non-zero exit (see the sibling "exited with non-zero status" error).

Solutions

  1. Increase the command's timeout via Cmd::timeout(...) at the call site
  2. Fix the underlying slowness (network, dependency resolution) that makes the command exceed the timeout
  3. Split the work into smaller commands so each fits within the timeout

Example fix

// before
let hashes = Cmd::new("cargo").args(["build"]).timeout(Some(Duration::from_secs(60)))
  .execute_hashes_async(MAX).await?; // timed out after 60s
// after
let hashes = Cmd::new("cargo").args(["build"]).timeout(Some(Duration::from_secs(600)))
  .execute_hashes_async(MAX).await?;
Defensive patterns

Strategy: try-catch

Try / catch

match cmd.execute_hashes_async(MAX).await {
    Ok(h) => Ok(h),
    Err(e) if e.to_string().starts_with("timed out after") => {
        warn!("command exceeded its timeout; consider raising it");
        Err(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling execute_hashes_async on a Cmd with a timeout set via .timeout(...), where the command runs longer than that duration and is killed by the guard, yielding a non-success status.

Common situations: Slow downloads or builds exceeding the task timeout, network-hanging commands (no connectivity), or an under-sized timeout for a legitimately long operation.

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.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d96b367824fb410b. Report an issue: GitHub.

Appendix: source

Thrown at src/cmd.rs:1470

                    bail!("command output pipes did not close within {pipe_drain_timeout:?}");
                }
            };
            if let Err(err) = consume(output) {
                #[cfg(unix)]
                signal_process_tree(id, nix::sys::signal::Signal::SIGKILL);
                #[cfg(windows)]
                kill_process_tree(id);
                return Err(err);
            }
        }

        if let Some(guard) = &timeout_guard {
            guard.cancel();
        }
        let status = status.expect("command wait must complete");
        if !status.success() {
            if let Some(timeout) = timeout_guard.as_ref().and_then(|guard| guard.timed_out()) {
                bail!("timed out after {timeout:?}");
            }
            bail!("exited with non-zero status: {status}");
        }
        Ok((
            stdout_hasher.finalize().to_hex().to_string(),
            stderr_hasher.finalize().to_hex().to_string(),
        ))
    }

    /// Run the command and return stdout, even when raw mode is enabled.
    pub(crate) async fn read(mut self) -> Result<String> {
        let _read_lock = raw_read_lock().await;
        debug!("$ {self}");
        self.cmd.kill_on_drop(true);
        #[cfg(unix)]
        if should_use_pgroup() {
            self.cmd.env(TASK_PGID_MANAGED_ENV, "1");
            unsafe {

View on GitHub (pinned to 533346cc37)