{"record":{"id":"cfacdbf831d24722","repo":"jdx/mise","slug":"variants-allow-only-one-default-without-os-or-pro","errorCode":null,"errorMessage":"variants allow only one default, without os or profile selectors","messagePattern":"variants allow only one default, without os or profile selectors","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/select.rs","lineNumber":92,"sourceCode":"#[derive(Debug, Clone, PartialEq, Eq)]\npub(crate) enum Selection {\n    /// The entry has no variants: one stream for every machine.\n    Single,\n    /// The variant this machine uses.\n    Variant(Variant),\n    /// No variant matches and none is the default: do not capture or apply.\n    NoMatch,\n    /// Two variants match with the same specificity.\n    Ambiguous(Vec<Variant>),\n}\n\n/// Reject fallbacks whose selectors would be ignored during selection.\npub(crate) fn validate(variants: &[Variant]) -> eyre::Result<()> {\n    let mut default_seen = false;\n    for variant in variants {\n        if variant.default {\n            if default_seen || !variant.os.is_empty() || variant.profile.is_some() {\n                eyre::bail!(\"variants allow only one default, without os or profile selectors\");\n            }\n            default_seen = true;\n        }\n    }\n    Ok(())\n}\n\n/// Picks the variant for this machine given the active mise environments.\npub(crate) fn select(variants: &[Variant], environments: &[String]) -> Selection {\n    if variants.is_empty() {\n        return Selection::Single;\n    }\n    let matching: Vec<&Variant> = variants\n        .iter()\n        .filter(|variant| !variant.default && variant.matches(environments))\n        .collect();\n    let best = matching.iter().map(|variant| variant.specificity()).max();\n    match best {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/select.rs#L74-L110","documentation":"Variant selection resolves a fallback by matching os/profile selectors and otherwise using the single default. A default variant carrying os or profile selectors would never be selected the way the author expects, and more than one default is ambiguous, so validate rejects both at load time.","triggerScenarios":"Defining a variants list where (a) two or more variants set default = true, or (b) a default variant also sets a non-empty os selector or a Some(profile) selector.","commonSituations":"Config authoring mistakes: duplicating a default when adding platform-specific variants; marking a linux-only variant as default; copy-pasting a selector-qualified variant and adding default = true.","solutions":["Keep exactly one default variant and remove os/profile selectors from it","Move os/profile-specific behavior to non-default variants with matching selectors","If multiple defaults were intentional, pick one and use selectors on the others"],"exampleFix":"# before\n[[variants]]\ndefault = true\nos = \"linux\"\n[[variants]]\ndefault = true\n# after\n[[variants]]\ndefault = true\n[[variants]]\nos = \"linux\"","handlingStrategy":"validation","validationCode":"let defaults: Vec<_> = variants.iter().filter(|v| v.default).collect();\nif defaults.len() != 1\n    || defaults.iter().any(|v| !v.os.is_empty() || v.profile.is_some())\n{\n    eprintln!(\"config invalid: exactly one selector-free default variant required\");\n}","typeGuard":null,"tryCatchPattern":"match variants::validate(&variants) {\n    Err(e) if e.to_string().contains(\"only one default\") => {\n        eprintln!(\"fix variants config: one default, no os/profile on the default\");\n    }\n    other => other?,\n}","preventionTips":["Keep exactly one selector-free default variant in every variants list","Put platform differences in non-default variants with os/profile selectors","Validate config after editing variants blocks"],"tags":["config","validation","variants"],"backgroundTag":"conflicting-config-options","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"}