{"record":{"id":"0d4c7e94b92b4542","repo":"jdx/mise","slug":"non-strict-resolve-is-infallible","errorCode":null,"errorMessage":"non-strict resolve is infallible","messagePattern":"non-strict resolve is infallible","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/mod.rs","lineNumber":668,"sourceCode":"                }\n            }\n        }\n    }\n}\n\n/// Aggregate `[bootstrap.packages]` across a specific set of config files.\npub(crate) fn packages_from_config_files(config_files: &ConfigMap) -> Vec<ManagerPackages> {\n    packages_from_config_files_with_brew_taps(config_files, &IndexMap::new(), true)\n}\n\nfn packages_from_config_files_with_brew_taps(\n    config_files: &ConfigMap,\n    brew_taps: &IndexMap<String, String>,\n    filter_env: bool,\n) -> Vec<ManagerPackages> {\n    let (requests, options) =\n        package_requests_from_config_files(config_files, brew_taps, filter_env);\n    resolve_managers(requests, options, false).expect(\"non-strict resolve is infallible\")\n}\n\nfn package_requests_from_config_files(\n    config_files: &ConfigMap,\n    brew_taps: &IndexMap<String, String>,\n    filter_env: bool,\n) -> (\n    IndexMap<String, Vec<PackageRequest>>,\n    IndexMap<String, ManagerPackageOptions>,\n) {\n    let merged = package_configs_from_config_files(config_files);\n    let mut by_mgr: IndexMap<String, Vec<PackageRequest>> = IndexMap::new();\n    #[cfg(unix)]\n    let brew_adopt = brew_adopt_from_config_files(config_files);\n    #[cfg(unix)]\n    let mut cask_adopt = BTreeSet::new();\n    for (spec, package) in merged {\n        if !package.is_os_supported() {","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/mod.rs#L650-L686","documentation":"`.expect(\"non-strict resolve is infallible\")` asserts that `resolve_managers(requests, options, false)` — i.e. resolution in non-strict mode — can never return `Err`. If it does, the assumption about non-strict mode's error behavior is broken (e.g. a code change made non-strict resolution fallible) and the process panics.","triggerScenarios":"Calling `resolve_managers_from_config_files` (src/system/mod.rs:668) after a refactor where non-strict mode now returns Err (e.g. missing manager binary or unparseable package spec no longer tolerated).","commonSituations":"Contributors changing `resolve_managers` error semantics without updating this call site; new failure classes (network taps, unknown managers) leaking into non-strict mode.","solutions":["Restore the invariant: make non-strict mode log-and-skip instead of returning Err","Change this call site to propagate the Result instead of expect-ing","If an error appears at runtime, check which manager/package input triggers it and fix the non-strict handling in resolve_managers"],"exampleFix":"// before\nresolve_managers(requests, options, false).expect(\"non-strict resolve is infallible\")\n// after\nresolve_managers(requests, options, false).unwrap_or_else(|e| {\n    warn!(\"skipping manager resolution failure: {e}\");\n    Vec::new()\n})","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match resolve_managers(requests, options, false) {\n    Ok(managers) => managers,\n    Err(e) => { warn!(\"non-strict resolve failed: {e}\"); Vec::new() }\n}","preventionTips":["Keep non-strict mode side-effect-free on error: skip and log","Add a regression test asserting non-strict resolve returns Ok for malformed inputs","When changing resolve_managers, grep for expect call sites"],"tags":["panic","invariant","package-resolution"],"backgroundTag":"internal-invariant-violation","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"}