{"record":{"id":"18c92d154f241c9e","repo":"jdx/mise","slug":"managed-system-path-must-be-absolute","errorCode":null,"errorMessage":"managed system path must be absolute: {}","messagePattern":"managed system path must be absolute: (.+?)","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":1371,"sourceCode":"            Self::File\n        } else if metadata.file_type().is_dir() {\n            Self::Directory\n        } else if metadata.file_type().is_symlink() {\n            Self::Symlink\n        } else {\n            Self::Other\n        }\n    }\n}\n\nfn absolute_target(path: &str) -> Result<PathBuf> {\n    let path = crate::file::replace_path(Path::new(path));\n    validate_privileged_target(&path)\n}\n\nfn validate_privileged_target(path: &Path) -> Result<PathBuf> {\n    if !path.is_absolute() {\n        bail!(\"managed system path must be absolute: {}\", path.display());\n    }\n    let path = path.absolutize()?.to_path_buf();\n    if path == Path::new(\"/\") {\n        bail!(\"refusing to manage the filesystem root\");\n    }\n    Ok(path)\n}\n\nfn parse_mode(mode: Option<&str>, default: u32) -> Result<u32> {\n    let Some(mode) = mode else {\n        return Ok(default);\n    };\n    let mode = mode.strip_prefix(\"0o\").unwrap_or(mode);\n    let parsed = u32::from_str_radix(mode, 8).wrap_err(\"mode must be an octal string\")?;\n    if parsed > 0o7777 {\n        bail!(\"mode must be between 0000 and 7777\");\n    }\n    Ok(parsed)","sourceCodeStart":1353,"sourceCodeEnd":1389,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/managed_files.rs#L1353-L1389","documentation":"Managed system files/directories must be declared with absolute paths, because they are applied by a privileged helper process whose working directory cannot be assumed. After `replace_path` substitution, `validate_privileged_target` rejects any relative path before absolutizing it.","triggerScenarios":"A [bootstrap.files] `path` (or directory path) that is relative, e.g. \"etc/myapp.conf\" or \"./conf\", passed through `validate_privileged_target` during planning.","commonSituations":"Hand-writing config with paths copied relative to the project root; templating that produced an empty or relative value; moving an entry from a project-local file list into bootstrap.files without absolutizing it.","solutions":["Change the path to an absolute one, e.g. path = \"/etc/myapp/app.conf\".","If the value was templated, fix the template/variable so it yields an absolute path.","Use mise's path templating to anchor the path (e.g. off a known absolute base) instead of a bare relative segment."],"exampleFix":"# before\n[bootstrap.files.appconf]\npath = \"etc/myapp/app.conf\"\n\n# after\n[bootstrap.files.appconf]\npath = \"/etc/myapp/app.conf\"\n","handlingStrategy":"validation","validationCode":"def assert_absent_free(p):\n    from pathlib import Path\n    p = Path(p)\n    if not p.is_absolute():\n        raise ValueError(f\"managed system path must be absolute: {p}\")\n    return p","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write [bootstrap.files]/[bootstrap.directories] paths with a leading \"/\".","Lint config for relative bootstrap paths in CI.","If using variables, assert they expand to absolute values."],"tags":["config","path","validation","bootstrap"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}