jdx/mise · warning

remote cleanup failed with {status}

Error message

remote cleanup failed with {status}

What it means

After running bootstrap work on the remote host, mise cleans up its staging directory with a remote `rm -rf` that is wrapped in a 5-second timeout. This error fires when the cleanup command exits non-zero within the timeout.

Source

Thrown at src/system/remote.rs:2105

                    shell_quote(remote)
                ),
            ],
            file,
        )
        .await
    }

    async fn cleanup(&self, path: &str) -> Result<()> {
        validate_staging_path(path)?;
        let mut command = tokio::process::Command::new(&self.ssh);
        command
            .args(self.args(false, &["rm", "-rf", "--", path]))
            .kill_on_drop(true);
        let status = tokio::time::timeout(std::time::Duration::from_secs(5), command.status())
            .await
            .map_err(|_| eyre!("remote cleanup timed out"))??;
        if !status.success() {
            bail!("remote cleanup failed with {status}");
        }
        Ok(())
    }

    async fn close(&self) {
        let Some(control_path) = &self.control_path else {
            return;
        };
        let mut command = tokio::process::Command::new(&self.ssh);
        command
            .kill_on_drop(true)
            .args(["-S"])
            .arg(control_path)
            .args(["-O", "exit"])
            .arg(self.host.destination())
            .stdout(Stdio::null())
            .stderr(Stdio::null());
        let status =

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Check whether the staging directory still exists remotely: `ssh <host> ls -d /tmp/mise-bootstrap.*` — if it is already gone, the failure is cosmetic.
  2. Verify the remote user can delete its own /tmp/mise-bootstrap.* directories (sticky-bit /tmp ownership).
  3. Inspect SSH health (`ssh <host> true`) and re-run; a transient connection drop is the usual cause.
  4. Manually remove leftovers: `ssh <host> rm -rf /tmp/mise-bootstrap.*`.
Defensive patterns

Strategy: try-catch

Try / catch

match cleanup_remote().await {
    Err(e) if e.to_string().contains("remote cleanup failed") => {
        // usually benign (already removed); optionally force-clean:
        let _ = ssh(&[host, "rm", "-rf", "/tmp/mise-bootstrap.*"]).await;
    }
    other => other?,
}

Prevention

When it happens

Trigger: The remote `rm -rf -- <staging path>` command (under `self.args(false, ...)`, i.e. without the interactive flag) returns a non-zero status — for example the staging path was already removed, permissions changed, or the SSH session is failing.

Common situations: Concurrent jobs deleting the same /tmp/mise-bootstrap.* directory, remote filesystem issues, or an SSH connection that is half-broken (auth works for some commands but the channel dies).

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/9e266abc0d85b194. Report an issue: GitHub.