jdx/mise · error
bootstrap_command returned an unsafe mise path
Error message
bootstrap_command returned an unsafe mise path: {command:?} What it means
mise runs a bootstrap command on a remote host to locate where mise was installed. Before using the returned string, `validated_remote_command` requires it to be an absolute path containing no NUL, newline, or carriage-return bytes; otherwise this error is thrown to prevent injecting arbitrary shell content or relative/truncated paths into remote shell commands.
Solutions
- Fix the remote bootstrap_command so it prints exactly one absolute path and nothing else (e.g. suppress rc-file output, use `command -v mise` with stderr redirected)
- Ensure mise is installed on the remote at a real absolute path (not an alias or shell function)
- Check for a broken remote helper/ssh wrapper emitting CR/LF or NUL bytes and fix its output encoding
Example fix
// before bootstrap_command = "mise which mise" // prints relative or extra lines // after bootstrap_command = "command -v mise 2>/dev/null" // single absolute path, stderr silenced
Defensive patterns
Strategy: validation
Validate before calling
function isSafeRemotePath(s) {
return typeof s === 'string' && s.startsWith('/') && !/[\0\n\r]/.test(s);
}
if (!isSafeRemotePath(output)) throw new Error('bootstrap output is not a safe absolute path'); Type guard
const isSafeRemotePath = (s: unknown): s is string =>
typeof s === 'string' && s.startsWith('/') && !/[\0\n\r]/.test(s); Try / catch
try {
let path = validated_remote_command(output);
} catch (e) {
if (String(e).includes('unsafe mise path')) {
// inspect raw remote output, fix bootstrap_command, then retry
} else throw e;
} Prevention
- Make bootstrap_command print exactly one absolute path to stdout and nothing else
- Send all diagnostics to stderr, never stdout
- Test the bootstrap command over plain ssh before wiring it into config
- Avoid relying on shell aliases/functions; use `command -v mise`
When it happens
Trigger: The remote `bootstrap_command` (e.g. `which mise`, `command -v mise`, or a custom script) prints a relative path, a multiline/annotated string (shell init output, MOTD text, aliases), or a path containing NUL/CR/LF.
Common situations: Custom bootstrap_command in remote.toml that echoes extra lines; remote shell rc-files printing banners before `which`; mise installed via an alias rather than a real path; NUL-corrupted output from a broken remote helper.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- returned an unsafe absolute path
- remote host ' ' bootstrap command contains NUL
- a provided source resolves to a path
- a validated copy_link has a staged parent
- brew-cask: command_wrapper requires a command name without…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/befd664e7e1095aa.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/remote.rs:2196
if value.is_empty() || value.contains('\0') {
bail!("remote {kind} cannot be empty or contain NUL");
}
Ok(())
}
fn validate_staging_path(path: &str) -> Result<()> {
if !path.starts_with("/tmp/mise-bootstrap.")
|| path["/tmp/mise-bootstrap.".len()..].is_empty()
|| path.chars().any(char::is_whitespace)
{
bail!("remote mktemp returned an unsafe staging path: {path:?}");
}
Ok(())
}
fn validated_remote_command(command: &str) -> Result<String> {
if !command.starts_with('/') || command.contains(['\0', '\n', '\r']) {
bail!("bootstrap_command returned an unsafe mise path: {command:?}");
}
Ok(command.to_string())
}
fn validated_remote_command_output(output: &str) -> Result<String> {
validated_remote_command(output.strip_suffix('\n').unwrap_or(output))
}
fn validated_absolute_remote_path_output(output: &str, kind: &str) -> Result<String> {
let path = output.strip_suffix('\n').unwrap_or(output);
if !path.starts_with('/') || path.contains(['\0', '\n', '\r']) {
bail!("{kind} returned an unsafe absolute path: {path:?}");
}
Ok(path.to_string())
}
fn validate_install_mise_path(path: &str) -> Result<()> {
validate_value("mise install path", path)?;View on GitHub (pinned to 533346cc37)