{"record":{"id":"81db7632567b3d3d","repo":"jdx/mise","slug":"system-files-were-preflighted-when-not-skipped","errorCode":null,"errorMessage":"system files were preflighted when not skipped","messagePattern":"system files were preflighted when not skipped","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/bootstrap.rs","lineNumber":1297,"sourceCode":"                    dry_run: self.dry_run,\n                    update: self.update,\n                    yes: self.yes,\n                };\n                driver::run(mgrs, Action::Install, &opts).await?;\n            }\n            if !has_plugin_packages {\n                self.run_hooks(&hooks, BootstrapHookPhase::PostPackages)\n                    .await?;\n                post_packages_ran = true;\n            }\n        }\n\n        if skip.contains(&BootstrapPart::Files) {\n            debug!(\"bootstrap: system files skipped\");\n        } else {\n            let (mut files, mut directories) = managed_system_files\n                .as_ref()\n                .expect(\"system files were preflighted when not skipped\")\n                .clone();\n            system::managed_files::inspect_requests(&mut files, &mut directories)?;\n            if files.is_empty() && directories.is_empty() {\n                debug!(\"bootstrap: no [bootstrap.files] or [bootstrap.directories] configured\");\n            } else {\n                info!(\"bootstrap: system files\");\n                let report = system::managed_files::apply_with_accounts(\n                    &files,\n                    &directories,\n                    configured_accounts.as_ref(),\n                    allow_pending_accounts,\n                    self.dry_run,\n                    self.yes,\n                )?;\n                notified_services = report.notified_services;\n            }\n        }\n","sourceCodeStart":1279,"sourceCodeEnd":1315,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/cli/bootstrap.rs#L1279-L1315","documentation":"Internal invariant in the apply phase of `mise bootstrap`. `managed_system_files` is Some exactly when the files part is enabled (`!skip.contains(&BootstrapPart::Files)`, src/cli/bootstrap.rs:1146-1152). At apply time the code re-checks `skip.contains(&BootstrapPart::Files)` and unwraps managed_system_files with this expect — the two conditions are complements, so the expect holds unless the skip set or the Option goes out of sync between preflight and apply.","triggerScenarios":"Only a code change that mutates `skip` or `managed_system_files` between preflight and the apply phase (e.g. a mid-run skip_parts() change), making files not-skipped while the Option is None — panics at the 'bootstrap: system files' step. No user configuration reaches it: `--skip=files` keeps both sides consistent.","commonSituations":"Contributors adding conditional file-part toggling mid-run; broken builds. Ordinary runs with or without --skip=files, --dry-run, or hooks do not hit it.","solutions":["If hit as a user: update/pin mise — internal bug, not config","Workaround: `mise bootstrap --skip=files` keeps both sides of the invariant on the skip path","As a contributor: compute `files_enabled` once and reuse it for both the Option construction and the apply-time check instead of re-reading skip","Report at https://github.com/jdx/mise/issues with the backtrace"],"exampleFix":"// before: skip re-evaluated at apply time, can diverge from preflight\nif skip.contains(&BootstrapPart::Files) { ... } else {\n    managed_system_files.as_ref().expect(\"system files were preflighted when not skipped\");\n}\n\n// after: reuse the preflight boolean\nif !files_enabled { debug!(\"bootstrap: system files skipped\"); } else {\n    let (mut files, mut directories) = managed_system_files\n        .expect(\"files_enabled implies preflight\") // single source of truth\n        .clone();\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass --skip=files explicitly when you do not want managed files applied — keeps skip state consistent","Prefer --dry-run to exercise the full preflight/apply flow safely","Report invariant panics upstream; they indicate divergent refactor state"],"tags":["bootstrap","invariant","panic","internal","managed-files"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}