jdx/mise · error
ambiguous variants for
Error message
ambiguous variants for {} What it means
`tracking` evaluates each enrollment entry against the active environments using the variant selector. If the selector returns `Selection::Ambiguous`, more than one variant matches the current environments and the tool cannot determine which variant's state applies, so it aborts with the enrollment path.
Solutions
- Make the variant matchers mutually exclusive so exactly one matches the active environments
- Remove or merge the duplicate/overlapping variant in the enrollment entry
- Use the tool's variant validation (super::select::validate) or a lint step on the manifest before syncing
- Check the selection error detail (`Ambiguous(_)` payload) to see which variants collided
Example fix
// before
variants: [{name:"laptop", when: host=="x"}, {name:"dev", when: host=="x"}]
// after
variants: [{name:"laptop", when: host=="x"}] // or differentiate `when` clauses Defensive patterns
Strategy: validation
Validate before calling
fn has_ambiguous_variants(entry: &Enrollment, envs: &Environments) -> bool {
matches!(select::select(&entry.variants, envs), select::Selection::Ambiguous(_))
} Try / catch
match manifest.tracking(&envs) {
Err(e) if e.to_string().starts_with("ambiguous variants") => {
eprintln!("fix overlapping variant matchers: {e}");
}
other => other,
} Prevention
- Keep variant matchers mutually exclusive per entry
- Run manifest validation/lint in CI before syncing
- Review the Ambiguous payload to see exactly which variants overlap
When it happens
Trigger: Calling `tracking` when an enrollment entry's `variants` list contains two or more variants whose environment predicates both match the current set of environments (e.g. overlapping matchers like two variants both matching the same hostname/OS).
Common situations: Hand-edited manifest with duplicate or overlapping variant conditions; adding a new variant that accidentally overlaps an existing one; a manifest synced from another machine with different variant rules.
Related errors
- invalid or repeated variant for
- multiple SwiftPM artifact bundles found
- : multiple [dotfiles] edit entries match; choose one of
- variants allow only one default, without os or profile…
- a provided source resolves to a path
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/e86fb10cebaa444f.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/manifest.rs:253
/// Restore enrollment from Git without needing a captured mise config.
/// Deployment inputs are validated separately; none are inferred here.
pub(crate) fn tracking(&self) -> Result<super::tracked::TrackedSet> {
self.validate()?;
let roots = super::sync::layout::Roots::current();
let environments = super::select::active_environments();
let mut tracked = super::tracked::TrackedSet {
manifest: self.clone(),
exclude: self.exclude.clone(),
..Default::default()
};
for enrollment in &self.enrollment {
let variant = match super::select::select(&enrollment.variants, &environments) {
super::select::Selection::Single => None,
super::select::Selection::Variant(variant) => Some(variant.name()),
super::select::Selection::NoMatch => continue,
super::select::Selection::Ambiguous(_) => {
bail!("ambiguous variants for {}", enrollment.path)
}
};
let local = roots
.locate(&enrollment.path)
.path()
.ok_or_else(|| eyre::eyre!("invalid enrollment path {}", enrollment.path))?
.to_path_buf();
super::tracked::ensure_portable_ancestors(&local)?;
let mut policy =
crate::system::files::FilePolicy::for_mode(crate::system::files::FileMode::Track);
policy.autosave = enrollment.autosave;
policy.encrypt = enrollment.encrypt;
let mut entry = super::tracked::TrackedEntry::new(local, "track", policy);
entry.variant = variant;
tracked.entries.push(entry);
}
Ok(tracked)
}View on GitHub (pinned to 533346cc37)