{"record":{"id":"0bf4cfa753aef94e","repo":"jdx/mise","slug":"configured-notifications-came-from-managed-files","errorCode":null,"errorMessage":"configured notifications came from managed files","messagePattern":"configured notifications came from managed files","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/bootstrap.rs","lineNumber":1395,"sourceCode":"        let services_enabled = !skip.contains(&BootstrapPart::Services);\n        let notifications_configured =\n            managed_system_files\n                .as_ref()\n                .is_some_and(|(files, directories)| {\n                    files.iter().any(|file| !file.notify.is_empty())\n                        || directories\n                            .iter()\n                            .any(|directory| !directory.notify.is_empty())\n                });\n        let configured_services = if services_enabled || notifications_configured {\n            Some(system::services::prepare_requests_from_config(&config)?)\n        } else {\n            None\n        };\n        if notifications_configured {\n            let (files, directories) = managed_system_files\n                .as_ref()\n                .expect(\"configured notifications came from managed files\");\n            let services = configured_services\n                .as_ref()\n                .expect(\"configured notifications prepared services\");\n            let user_services = system::services_common::user_service_names(&config)?;\n            system::services::validate_notifications(files, directories, services, &user_services)?;\n        }\n        let mut managed_services =\n            services_enabled.then_some(configured_services.unwrap_or_default());\n        let user_services = if services_enabled {\n            system::user_services::requests_from_config(&config)?\n        } else {\n            vec![]\n        };\n        let mut managed_firewall = if skip.contains(&BootstrapPart::Firewall) {\n            None\n        } else {\n            system::firewall::prepare_request_from_config(&config)?\n        };","sourceCodeStart":1377,"sourceCodeEnd":1413,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/bootstrap.rs#L1377-L1413","documentation":"This is a Rust panic from `.expect()` in mise's bootstrap command (src/cli/bootstrap.rs:1395). It is an internal invariant assertion: notifications are only marked as configured when the system-file preflight pass produced managed files/directories. The panic means notifications validation started without that preflight result, i.e. bootstrap phases were run out of order or the files phase was skipped.","triggerScenarios":"`notifications_configured` is true (a [notifications] bootstrap config exists) while `managed_system_files` is None — typically because the BootstrapPart::Files preflight was skipped via the skip list or the preflight function was not called before the notifications validation block.","commonSituations":"Running a partial bootstrap (a skip list used by tests or `mise bootstrap --only`) that includes notifications but excludes the files preflight; refactors that reorder bootstrap phases.","solutions":["Ensure the bootstrap run includes the Files part (remove BootstrapPart::Files from the skip list) whenever notifications are configured","Run the managed-system-files preflight before the notifications validation block","Check for code changes that set notifications_configured without running preflight; restore the invariant or make the value Option-aware"],"exampleFix":"// before\nlet (files, directories) = managed_system_files.as_ref().expect(\"configured notifications came from managed files\");\n// after\nlet Some((files, directories)) = managed_system_files.as_ref() else { debug!(\"bootstrap: notifications skipped, no managed files\"); return Ok(()); };","handlingStrategy":"validation","validationCode":"if notifications_configured && managed_system_files.is_none() { return Err(anyhow!(\"notifications configured but system-file preflight did not run\")); }","typeGuard":"let files_ready = managed_system_files.as_ref().map(|(f, d)| !f.is_empty() || !d.is_empty()).unwrap_or(false);","tryCatchPattern":"match managed_system_files.as_ref() { Some((f, d)) => validate_notifications(f, d, ...)?, None => bail!(\"managed system files missing for notifications\"), }","preventionTips":["Keep bootstrap phase ordering centralized so preflight always precedes validation","Never add a bootstrap part to the skip list without checking its dependents","Cover phase combinations (notifications + skipped files) with tests"],"tags":["rust","panic","bootstrap","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}