jdx/mise · error · eyre::Report
refusing to manage the filesystem root
Error message
refusing to manage the filesystem root
What it means
After absolutizing, a managed path equal to "/" is rejected because managing (creating, replacing, or deleting) the filesystem root is always destructive and never a legitimate declaration. `validate_privileged_target` blocks it explicitly as a safety rail.
Solutions
- Correct the path to the specific file or directory actually intended (e.g. "/etc/myapp").
- Check any variables used in the path — one of them is expanding to "/" or empty; give it a real value.
- If the entry is leftover scaffolding, remove it from the config entirely.
Example fix
# before
[bootstrap.directories.appdata]
path = "{{base_dir}}" # base_dir resolves to "/"
# after
[bootstrap.directories.appdata]
path = "/var/lib/myapp"
Defensive patterns
Strategy: validation
Validate before calling
def assert_not_root(p):
import os
r = os.path.realpath(os.path.expanduser(p))
if r == '/':
raise ValueError(f"refusing to manage filesystem root: {p}")
return r Prevention
- Never let path variables default to "/" or empty.
- Lint for path == "/" after variable expansion in CI.
- Always include a concrete final path component in declarations.
When it happens
Trigger: A [bootstrap.files]/[bootstrap.directories] entry whose path resolves to "/" — either literally, via a variable that expands to empty/root, or via `replace_path` substitution producing "/".
Common situations: A template variable like `${base_dir}` left unset or set to "/"; typo where the final path component was dropped ("/etc/myapp/" mishandled by tooling); experimentation gone wrong.
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
- managed system path must be absolute
- refusing to replace non-directory path
- relative repo path ` ` must name a directory inside the…
- a provided source resolves to a path
- [bootstrap].config_roots did not match any config roots
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/73ab44503d3f6d1a.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/managed_files.rs:1375
Self::Symlink
} else {
Self::Other
}
}
}
fn absolute_target(path: &str) -> Result<PathBuf> {
let path = crate::file::replace_path(Path::new(path));
validate_privileged_target(&path)
}
fn validate_privileged_target(path: &Path) -> Result<PathBuf> {
if !path.is_absolute() {
bail!("managed system path must be absolute: {}", path.display());
}
let path = path.absolutize()?.to_path_buf();
if path == Path::new("/") {
bail!("refusing to manage the filesystem root");
}
Ok(path)
}
fn parse_mode(mode: Option<&str>, default: u32) -> Result<u32> {
let Some(mode) = mode else {
return Ok(default);
};
let mode = mode.strip_prefix("0o").unwrap_or(mode);
let parsed = u32::from_str_radix(mode, 8).wrap_err("mode must be an octal string")?;
if parsed > 0o7777 {
bail!("mode must be between 0000 and 7777");
}
Ok(parsed)
}
fn nonempty(field: &str, value: Option<String>) -> Result<Option<String>> {
match value {View on GitHub (pinned to 533346cc37)