{"record":{"id":"f0176208414c5bd5","repo":"jdx/mise","slug":"artifact-directory-was-initialized","errorCode":null,"errorMessage":"artifact directory was initialized","messagePattern":"artifact directory was initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1511,"sourceCode":"            .ok_or_else(|| eyre!(\"signed mise release manifest does not contain {asset}\"))\n    }\n}\n\nimpl RemoteArtifactResolver {\n    async fn resolve(&mut self, platform: &RemotePlatform, local: &Path) -> Result<PathBuf> {\n        let asset = platform.release_asset_name()?;\n        if let Some(path) = self.artifacts.get(&asset) {\n            return Ok(path.clone());\n        }\n        self.ensure_official_local(local).await?;\n        let checksum = self.manifest().await?.checksum(&asset)?.to_string();\n        if self.directory.is_none() {\n            self.directory = Some(tempfile::tempdir()?);\n        }\n        let path = self\n            .directory\n            .as_ref()\n            .expect(\"artifact directory was initialized\")\n            .path()\n            .join(&asset);\n        let progress = MultiProgressReport::get().add(\"mise bootstrap\");\n        progress.set_message(format!(\"downloading {asset}\"));\n        if let Err(error) = HTTP\n            .download_file(release_url(&asset), &path, Some(progress.as_ref()))\n            .await\n        {\n            progress.abandon();\n            return Err(error).wrap_err_with(|| {\n                format!(\"failed to download official mise release artifact {asset}\")\n            });\n        }\n        progress.set_message(format!(\"verifying {asset}\"));\n        if let Err(error) =\n            crate::hash::ensure_checksum(&path, &checksum, Some(progress.as_ref()), \"sha256\")\n        {\n            progress.abandon();","sourceCodeStart":1493,"sourceCodeEnd":1529,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/remote.rs#L1493-L1529","documentation":"A Rust internal invariant panic: after lazily initializing a temporary download directory at the start of the bootstrap download routine, the code expects the Option to be Some. If it is None the code would be internally inconsistent (the init just above guarantees it), so this expect only fires on a logic bug or concurrent mutation, not on user input.","triggerScenarios":"Calling the bootstrap/artifact download path (e.g. mise bootstrap release download) when the artifact directory was somehow not initialized by the preceding is_none() branch — e.g. a refactor removed the init, or a concurrent borrow cleared self.directory between init and use.","commonSituations":"Practically never hit by end users; appears during development when the lazy-init code above is edited, or in exotic concurrent-mutation bugs in a modified build.","solutions":["Verify the preceding `if self.directory.is_none() { ... }` init block is still present and executes before the expect","Check that tempdir() creation isn't being skipped behind a feature flag or early return","Ensure no other code path sets self.directory back to None between init and use","If hit in a stock build, report it as a bug with the command run"],"exampleFix":"// before\nself.directory = Some(tempfile::tempdir()?);\n// after\nif self.directory.is_none() {\n    self.directory = Some(tempfile::tempdir()?);\n}\n// (keep the init unconditionally reachable before the expect)","handlingStrategy":"validation","validationCode":"if self.directory.is_none() {\n    self.directory = Some(tempfile::tempdir()?);\n}\ndebug_assert!(self.directory.is_some(), \"artifact directory initialized\");","typeGuard":"fn artifact_dir_ready(state: &State) -> bool { state.directory.is_some() }","tryCatchPattern":"std::panic::catch_unwind(|| bootstrap_download(...)).map_err(|_| \"internal error: artifact dir uninitialized\")","preventionTips":["Keep lazy-init blocks adjacent to the expect that depends on them","Prefer returning Result over expect for state that can legitimately fail to initialize","Add unit tests covering the lazy-init path"],"tags":["rust","internal-invariant","panic","filesystem"],"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"}