{"record":{"id":"75f15e459f51c9eb","repo":"jdx/mise","slug":"invalid-or-repeated-enrollment-path","errorCode":null,"errorMessage":"invalid or repeated enrollment path {}","messagePattern":"invalid or repeated enrollment path (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/manifest.rs","lineNumber":368,"sourceCode":"                });\n            }\n        }\n        repo.compose(tree, &overlays)\n    }\n\n    pub(crate) fn validate(&self) -> Result<()> {\n        if self.format != 1 {\n            bail!(\"unsupported dotfile repository format {}\", self.format);\n        }\n        let mut paths = std::collections::BTreeSet::new();\n        for entry in &self.enrollment {\n            if !super::sync::layout::is_safe_branch_path(&entry.path)\n                || !(entry.path.starts_with(\"home/\")\n                    || entry.path == \"config\"\n                    || entry.path.starts_with(\"config/\"))\n                || !paths.insert(&entry.path)\n            {\n                bail!(\"invalid or repeated enrollment path {}\", entry.path);\n            }\n            let mut variants = std::collections::BTreeSet::new();\n            super::select::validate(&entry.variants)?;\n            for variant in &entry.variants {\n                let name = variant.name();\n                if name.contains('@')\n                    || !super::sync::layout::is_safe_branch_path(&name)\n                    || !variants.insert(name)\n                {\n                    bail!(\"invalid or repeated variant for {}\", entry.path);\n                }\n            }\n        }\n        for (path, bits) in &self.permissions {\n            if *bits > 0o777\n                || !super::sync::layout::is_safe_branch_path(path)\n                || !self.owns_stream(path)\n            {","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/manifest.rs#L350-L386","documentation":"Thrown by `Manifest::validate` when an enrollment path fails `is_safe_branch_path`, is not under `home/` or `config`/`config/`, or duplicates a path already enrolled. Each enrollment must map to a unique, portable branch path in the dotfile repository.","triggerScenarios":"Enrolling a path containing traversal (`..`), absolute paths, invalid branch-path characters, paths outside the home/config roots, or enrolling the same file twice (insert into the BTreeSet fails).","commonSituations":"Hand-editing the manifest and introducing a duplicate entry or Windows-style path; enrolling a file outside the allowed roots; path entries with spaces or special characters unsafe as git branch names.","solutions":["Remove duplicate enrollment entries, keeping one entry per path.","Rewrite the path to a safe branch form relative to `home/` or `config/`.","Move the file under an allowed root or stop enrolling it through this mechanism.","Sanitize the path (no `..`, no invalid branch characters) before adding to the manifest."],"exampleFix":"// before\n[[enrollment]]\npath = \"/etc/nginx/nginx.conf\"\n// after\n[[enrollment]]\npath = \"config/nginx/nginx.conf\"","handlingStrategy":"validation","validationCode":"// check path safety + uniqueness before enrolling:\n// case \"$p\" in home/*|config|config/*) ;; *) echo \"bad path $p\";; esac\n// grep -c \"path = \\\"$p\\\"\" manifest | grep -q '^1$' || echo \"duplicate\"","typeGuard":null,"tryCatchPattern":"// on \"invalid or repeated enrollment path {path}\": remove duplicates\n// or correct the path in the manifest, then retry","preventionTips":["Enroll only files under home/ or config/.","Enforce one entry per path in the manifest.","Use the tool's enroll command instead of hand-editing paths."],"tags":["manifest","path-validation","duplicate","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}