jdx/mise · error
relative remote mise path escapes the staged project: {comma
Error message
relative remote mise path escapes the staged project: {command:?} What it means
For relative remote mise paths, mise normalizes components and rejects any path that would climb above the staged project root: when a ".." component has no matching parent component left, the path escapes the project and mise bails instead of executing outside it.
Source
Thrown at src/system/remote.rs:1252
) -> Result<String> {
if command.starts_with('/') {
return Ok(command.to_string());
}
if let Some(suffix) = command.strip_prefix("~/") {
if suffix.is_empty() {
bail!("remote mise path does not name an executable: {command:?}");
}
let home = remote_home.ok_or_else(|| eyre!("remote login home was not resolved"))?;
return Ok(format!("{}/{suffix}", home.trim_end_matches('/')));
}
let mut components = Vec::new();
for component in command.split('/') {
match component {
"" | "." => {}
".." => {
if components.pop().is_none() {
bail!("relative remote mise path escapes the staged project: {command:?}");
}
}
component => components.push(component),
}
}
if components.is_empty() {
bail!("relative remote mise path does not name an executable: {command:?}");
}
Ok(format!("{project}/{}", components.join("/")))
}
fn remote_mise_find_script() -> &'static str {
r#"mise_path=$(command -v mise 2>/dev/null || true)
case "$mise_path" in /*) ;; *) mise_path= ;; esac
if [ -z "$mise_path" ]; then
for candidate in "$HOME/.local/bin/mise" "$HOME/.local/share/mise/bin/mise" "$HOME/.cargo/bin/mise" /usr/local/bin/mise /opt/homebrew/bin/mise; do
if [ -x "$candidate" ]; then
mise_path=$candidateView on GitHub (pinned to afd2eddd3a)
Solutions
- Use a path that stays within the staged project, e.g. "bin/mise" or "./mise"
- Use an absolute path (starting with /) or home-relative "~/..." if the binary lives elsewhere
- Install mise at the default location so no relative path is needed
Example fix
// before remote_mise = "../tools/mise" // after remote_mise = "~/tools/mise"
Defensive patterns
Strategy: validation
Validate before calling
function staysInProject(rel) {
let depth = 0;
for (const seg of rel.split('/')) {
if (seg === '..') { depth--; if (depth < 0) return false; }
else if (seg && seg !== '.') depth++;
}
return true;
} Type guard
const inProject = (rel) => !path.posix.isAbsolute(rel) && !rel.split('/').reduce((d,s)=> s==='..'? d-1 : (s&&s!=='.')? d+1 : d, 0) < 0 === false; Prevention
- Keep relative remote paths rooted at the staged project
- Use ~/ or absolute paths for binaries outside the project
- Lint remote path settings for '..' segments
When it happens
Trigger: Supplying a relative remote mise command like "../tools/mise" or "a/../../mise" whose normalization would resolve outside the staged project directory.
Common situations: Users assuming relative paths are relative to CWD or home rather than the staged project; paths copied from layouts where mise sat in a sibling directory.
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
- copy_link must be a relative path within the source: {}
- copy_link cannot be nested below a symbolic link: {}
- copy_link is not a symbolic link: {}
- remote mise path does not name an executable: {command:?}
- relative remote mise path does not name an executable: {comm
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/71bfd941be12ee6a.
Report an issue: GitHub.