{"record":{"id":"4a237cdd70d0ce5c","repo":"jdx/mise","slug":"invalid-or-repeated-variant-for","errorCode":null,"errorMessage":"invalid or repeated variant for {}","messagePattern":"invalid or repeated variant for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/manifest.rs","lineNumber":378,"sourceCode":"        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            {\n                bail!(\"invalid or unenrolled permission path {path}\");\n            }\n        }\n        Ok(())\n    }\n\n    pub(crate) fn read(repo: &HistoryRepo, tree: &str) -> Result<Option<Self>> {\n        let Some((mode, oid)) = repo.object_at(tree, PATH)? else {\n            return Ok(None);\n        };","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/manifest.rs#L360-L396","documentation":"Variant names inside an enrollment entry must be safe branch path names, must not contain '@', and must be unique within the entry. `validate` bails when a variant name violates any of these rules, keeping variant names usable as branch/path components.","triggerScenarios":"Calling `validate` (via `tracking`, `write`, or permission capture) with an entry whose variant name contains '@', includes unsafe path characters or `..` segments, or repeats a name already used by another variant in the same entry.","commonSituations":"Naming variants with machine identifiers containing '@' (e.g. `user@host`); copy/pasting a variant and forgetting to rename it; using spaces or special characters in variant names.","solutions":["Rename the variant to a safe, unique branch-path-style name without '@' (e.g. use a hyphen instead of '@')","Remove duplicate variant entries within the enrollment","Validate variant names with the same rules you'd apply to file/branch names (no `..`, no separators/unsafe chars)"],"exampleFix":"// before\nvariants = [\"user@host\", \"laptop\"]\n// after\nvariants = [\"user-host\", \"laptop\"]","handlingStrategy":"validation","validationCode":"fn variant_ok(name: &str, seen: &mut std::collections::BTreeSet<&str>) -> bool {\n  !name.contains('@') && is_safe_branch_path(name) && seen.insert(name)\n}","typeGuard":null,"tryCatchPattern":"match manifest.validate() {\n  Err(e) if e.to_string().starts_with(\"invalid or repeated variant\") => {\n    // rename/deduplicate variants, then re-validate\n  }\n  other => other,\n}","preventionTips":["Avoid '@' and special characters in variant names; prefer [a-z0-9-]","Ensure variant names are unique within each enrollment entry","Lint manifests after copy/pasting or merging entries"],"tags":["manifest","validation","naming","variants"],"backgroundTag":"invalid-identifier-format","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"}