jdx/mise · error
artifact directory was initialized
Error message
artifact directory was initialized
What it means
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.
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
Example fix
// before
self.directory = Some(tempfile::tempdir()?);
// after
if self.directory.is_none() {
self.directory = Some(tempfile::tempdir()?);
}
// (keep the init unconditionally reachable before the expect) Defensive patterns
Strategy: validation
Validate before calling
if self.directory.is_none() {
self.directory = Some(tempfile::tempdir()?);
}
debug_assert!(self.directory.is_some(), "artifact directory initialized"); Type guard
fn artifact_dir_ready(state: &State) -> bool { state.directory.is_some() } Try / catch
std::panic::catch_unwind(|| bootstrap_download(...)).map_err(|_| "internal error: artifact dir uninitialized")
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- command wait must complete
- executor must be initialized before displaying cache stats
- executor must be initialized before running tasks
- generated mise usage spec
- GitHub API URL should be valid
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/f0176208414c5bd5.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/remote.rs:1511
.ok_or_else(|| eyre!("signed mise release manifest does not contain {asset}"))
}
}
impl RemoteArtifactResolver {
async fn resolve(&mut self, platform: &RemotePlatform, local: &Path) -> Result<PathBuf> {
let asset = platform.release_asset_name()?;
if let Some(path) = self.artifacts.get(&asset) {
return Ok(path.clone());
}
self.ensure_official_local(local).await?;
let checksum = self.manifest().await?.checksum(&asset)?.to_string();
if self.directory.is_none() {
self.directory = Some(tempfile::tempdir()?);
}
let path = self
.directory
.as_ref()
.expect("artifact directory was initialized")
.path()
.join(&asset);
let progress = MultiProgressReport::get().add("mise bootstrap");
progress.set_message(format!("downloading {asset}"));
if let Err(error) = HTTP
.download_file(release_url(&asset), &path, Some(progress.as_ref()))
.await
{
progress.abandon();
return Err(error).wrap_err_with(|| {
format!("failed to download official mise release artifact {asset}")
});
}
progress.set_message(format!("verifying {asset}"));
if let Err(error) =
crate::hash::ensure_checksum(&path, &checksum, Some(progress.as_ref()), "sha256")
{
progress.abandon();View on GitHub (pinned to 533346cc37)