jdx/mise · error
install_mise must not contain '..
Error message
install_mise must not contain '..': {path:?} What it means
`validate_install_mise_path` rejects any `install_mise` value containing a '..' path component. Parent-directory traversal in a remotely executed path can escape the intended install directory and is a command-injection/safety hazard, so mise blocks it outright.
Solutions
- Rewrite the path without '..' components (normalize it yourself to the final absolute path)
- Fix the templating/variable interpolation that injects '..' into the value
- Verify the config file was not tampered with if '..' appears unexpectedly
Example fix
// before install_mise = "/opt/../usr/local/bin/mise" // after install_mise = '/usr/local/bin/mise'
Defensive patterns
Strategy: validation
Validate before calling
if (p.split('/').includes('..')) throw new Error('install_mise must not contain ..'); Type guard
const hasNoDotDot = (s: unknown): s is string =>
typeof s === 'string' && !s.split('/').includes('..'); Try / catch
try { validate_install_mise_path(p)?; } catch (e) {
if (String(e).includes("'..'")) { /* normalize the path and retry */ }
} Prevention
- Normalize templated paths before writing them to config
- Never concatenate untrusted variables into install paths
- Add a config linter rejecting '..' components
- Review shared config changes for path-traversal patterns
When it happens
Trigger: install_mise contains '/..' or ends with '..' e.g. '/opt/../bin/mise' or '~/mise/..' — typically from templated paths or variables that interpolate to '..'.
Common situations: Config templates concatenating variables that yield '..'; typos like '/usr/local/bin/../mise'; attempting path tricks in shared config files.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- a provided source resolves to a path
- [dotfiles]." ": target is not a safe OCI path
- install_mise must be an absolute path or start with ~/
- install_mise must name an executable file
- install_mise must not contain a newline
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/2b934f2204c7668c.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/remote.rs:2222
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)?;
if path.contains(['\n', '\r']) {
bail!("install_mise must not contain a newline: {path:?}");
}
if !path.starts_with('/') && !path.starts_with("~/") {
bail!("install_mise must be an absolute path or start with ~/: {path:?}");
}
if path.split('/').any(|component| component == "..") {
bail!("install_mise must not contain '..': {path:?}");
}
if matches!(
path.rsplit('/').next(),
None | Some("") | Some(".") | Some("~")
) {
bail!("install_mise must name an executable file: {path:?}");
}
Ok(())
}
fn validate_remote_executable(command: &str) -> Result<()> {
validate_value("mise command", command)?;
let is_path = command.contains('/');
if command.starts_with('-')
|| command.contains(['\n', '\r'])
|| (!is_path && command.chars().any(char::is_whitespace))
{
bail!("remote mise command must be an executable name or path: {command:?}");View on GitHub (pinned to 533346cc37)