{"record":{"id":"ca071ac2d58b6fff","repo":"jdx/mise","slug":"provider-checked-above","errorCode":null,"errorMessage":"provider checked above","messagePattern":"provider checked above","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/deps/install.rs","lineNumber":114,"sourceCode":"        let mut ts = match &monorepo_union {\n            Some(union) => {\n                let mut ts: Toolset = union.tool_request_set.clone().into();\n                ts.resolve(&install_config).await?;\n                ts\n            }\n            None => {\n                ToolsetBuilder::new()\n                    .with_default_to_latest(true)\n                    .build(&install_config)\n                    .await?\n            }\n        };\n\n        if self.explain {\n            let env = ts.env_with_path(&install_config).await?;\n            return Self::explain_provider(\n                &engine,\n                self.provider.as_deref().expect(\"provider checked above\"),\n                &env,\n            );\n        }\n\n        let install_opts = InstallOptions {\n            missing_args_only: false,\n            dry_run: self.dry_run,\n            ..Default::default()\n        };\n        ts.install_missing_versions(&mut install_config, &install_opts)\n            .await?;\n\n        // Get toolset environment with PATH\n        let (env, env_remove) = ts.env_with_path_and_removals(&install_config).await?;\n\n        let opts = DepsOptions {\n            dry_run: self.dry_run,\n            force: self.force,","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/deps/install.rs#L96-L132","documentation":"A `.expect()` panic in `mise deps install --explain` (src/cli/deps/install.rs:114). The code assumes a preceding check ensured `--provider` is present whenever `--explain` is used; the expect asserts that. Panicking means `--explain` reached the explain path without a provider, so the upstream guard is missing or bypassed.","triggerScenarios":"Running `mise deps install --explain` without `--provider` when the validation earlier in `run` does not actually reject that combination (e.g. provider default logic changed or the check was removed).","commonSituations":"Calling the explain code path programmatically or via a new subcommand wrapper that skips the argument validation; CLI changes that made --provider optional.","solutions":["Pass `--provider <name>` together with `--explain`","Restore/verify the early guard that errors when explain is set without provider","Return a clap validation error instead of panicking (make --provider required_with \"explain\")"],"exampleFix":"// before\nself.provider.as_deref().expect(\"provider checked above\")\n// after\nself.provider.as_deref().ok_or_else(|| anyhow!(\"--provider is required with --explain\"))?","handlingStrategy":"validation","validationCode":"if self.explain && self.provider.is_none() { return Err(anyhow!(\"--provider is required with --explain\")); }","typeGuard":"let provider = match (self.explain, self.provider.as_deref()) { (true, Some(p)) => Some(p), (true, None) => return Err(anyhow!(\"missing --provider\")), _ => None };","tryCatchPattern":"let Some(provider) = self.provider.as_deref().filter(|_| self.explain) else { return Err(anyhow!(\"--explain requires --provider\")) };","preventionTips":["Always pass --provider alongside --explain","Encode the requirement with clap `required_with = \"explain\"`","Keep the argument guard immediately before the branch that consumes it"],"tags":["cli","deps","missing-argument","panic"],"backgroundTag":"missing-required-flag","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"}