{"record":{"id":"7aaa66a418bfdd59","repo":"jdx/mise","slug":"release-manifest-was-loaded","errorCode":null,"errorMessage":"release manifest was loaded","messagePattern":"release manifest was loaded","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":1589,"sourceCode":"    }\n\n    async fn manifest(&mut self) -> Result<&ReleaseManifest> {\n        if self.manifest.is_none() {\n            let manifest_url = release_url(\"SHASUMS256.txt\");\n            let signature_url = release_url(\"SHASUMS256.txt.minisig\");\n            let (contents, signature) = tokio::try_join!(\n                HTTP.get_text_cached(&manifest_url),\n                HTTP.get_text_cached(&signature_url)\n            )\n            .wrap_err_with(|| {\n                format!(\n                    \"failed to fetch signed mise {} release checksums\",\n                    env!(\"CARGO_PKG_VERSION\")\n                )\n            })?;\n            self.manifest = Some(ReleaseManifest::verified(&contents, &signature)?);\n        }\n        Ok(self.manifest.as_ref().expect(\"release manifest was loaded\"))\n    }\n}\n\nfn release_url(filename: &str) -> String {\n    let version = env!(\"CARGO_PKG_VERSION\");\n    format!(\"{RELEASE_BASE_URL}/v{version}/{filename}\")\n}\n\nfn release_asset_name(os: &str, arch: &str, libc: Option<LibcFlavor>) -> Result<String> {\n    let release_arch = match arch {\n        \"x86_64\" => \"x64\",\n        \"aarch64\" => \"arm64\",\n        \"armv7\" => \"armv7\",\n        _ => {\n            bail!(\n                \"mise {} has no official precompiled artifact for {os}/{arch}; set mise_bin, remote_mise, or bootstrap_command\",\n                env!(\"CARGO_PKG_VERSION\")\n            )","sourceCodeStart":1571,"sourceCodeEnd":1607,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/remote.rs#L1571-L1607","documentation":"A Rust internal invariant panic in the release-manifest loader: the code fetches and verifies the signed release manifest and stores it in self.manifest, then immediately unwraps it with expect. The expect can only fire if manifest loading was skipped or failed silently before this accessor is called, i.e. an internal state bug rather than a network problem (network errors surface earlier as the 'failed to fetch' error).","triggerScenarios":"Calling the manifest accessor (returns &ReleaseManifest) without having triggered the load branch — e.g. a refactor made the load conditional, an early return bypassed `self.manifest = Some(...)`.","commonSituations":"Seen during development when changing the lazy-load logic; users may see it as a panic during mise bootstrap if a modified build skips verification.","solutions":["Ensure the fetch+verify branch runs before the accessor returns (no early returns between them)","Check ReleaseManifest::verified isn't short-circuited by caching logic that leaves manifest as None","If the load can legitimately fail, propagate the error instead of reaching the expect","Report with the exact command and version if hit in an unmodified build"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure load happened\nself.ensure_manifest_loaded()?;\ndebug_assert!(self.manifest.is_some());","typeGuard":"fn manifest_loaded(state: &State) -> bool { state.manifest.is_some() }","tryCatchPattern":"let manifest = loader.manifest().map_err(|e| anyhow!(\"manifest unavailable: {e}\"))?;","preventionTips":["Make lazy accessors load-or-error instead of expecting preloaded state","Cover the fetch/verify branch with tests before refactoring","Never add early returns between load and access"],"tags":["rust","internal-invariant","panic","release-manifest"],"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"}