{"record":{"id":"c9bfcdc85c941cc9","repo":"jdx/mise","slug":"bootstrappart-values-have-clap-names","errorCode":null,"errorMessage":"BootstrapPart values have clap names","messagePattern":"BootstrapPart values have clap names","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/bootstrap.rs","lineNumber":2469,"sourceCode":"    }\n    if all {\n        for (name, host) in inventory {\n            selected.entry(name.clone()).or_insert_with(|| host.clone());\n        }\n    }\n    if !tags.is_empty() {\n        for (name, host) in inventory {\n            if tags.iter().any(|tag| host.tags.contains(tag)) {\n                selected.entry(name.clone()).or_insert_with(|| host.clone());\n            }\n        }\n    }\n    Ok(selected)\n}\n\nfn bootstrap_part_name(part: &BootstrapPart) -> String {\n    part.to_possible_value()\n        .expect(\"BootstrapPart values have clap names\")\n        .get_name()\n        .to_string()\n}\n\nimpl BootstrapSecretsStatus {\n    async fn run(self) -> Result<()> {\n        let config = Config::get().await?;\n        let statuses = system::secrets::statuses(&config)?;\n        let unavailable = statuses\n            .iter()\n            .any(|status| status.state != system::secrets::SecretState::Available);\n        if self.json {\n            miseprintln!(\"{}\", serde_json::to_string_pretty(&statuses)?);\n        } else if statuses.is_empty() {\n            info!(\"no bootstrap secret inputs configured\");\n        } else {\n            let mut table = MiseTable::new(false, &[\"Secret\", \"Environment\", \"State\"]);\n            for status in statuses {","sourceCodeStart":2451,"sourceCodeEnd":2487,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/cli/bootstrap.rs#L2451-L2487","documentation":"bootstrap_part_name converts a BootstrapPart enum value to its clap name via `part.to_possible_value().expect(\"BootstrapPart values have clap names\")` (src/cli/bootstrap.rs:2468-2473). Because BootstrapPart derives clap's ValueEnum, every variant has a possible value with a name; the expect only fails if a variant is added without ValueEnum support (e.g. a custom impl or #[value(skip)] variant). It is a compile-time-adjacent invariant enforced at runtime.","triggerScenarios":"A contributor adds a new BootstrapPart variant (a new bootstrap part) whose ValueEnum implementation returns None from to_possible_value — then any code path formatting skip/only part names panics. No user input reaches it: the parts come from the fixed enum, parsed by clap itself.","commonSituations":"Development of new bootstrap parts; broken custom builds. End users cannot construct a BootstrapPart that lacks a clap name because clap rejects unknown --skip/--only values before this code runs.","solutions":["If hit as a user: update mise — the build contains an unsupported bootstrap part variant","As a contributor: ensure every BootstrapPart variant is a plain ValueEnum variant (no #[value(skip)]) or extend the enum's impl so to_possible_value returns a name","Add a unit test asserting to_possible_value().is_some() for all BootstrapPart::value_variants()","Report at https://github.com/jdx/mise/issues"],"exampleFix":"// before: variant hidden from clap\n#[derive(clap::ValueEnum, Clone)]\nenum BootstrapPart {\n    Accounts,\n    Files,\n    #[value(skip)]\n    InternalOnly, // to_possible_value() -> None -> panic\n}\n\n// after: every variant carries a clap name\n#[derive(clap::ValueEnum, Clone)]\nenum BootstrapPart {\n    Accounts,\n    Files,\n    InternalOnly, // named; hidden from help via clap's hide mechanism if needed\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use released mise builds; this invariant guards enum/clap wiring only contributors can break","Contributors: unit-test BootstrapPart::value_variants() all have to_possible_value() names","Report panic backtraces upstream"],"tags":["bootstrap","invariant","panic","internal","clap"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}