jdx/mise · error
MISE_BIN should have a parent directory
Error message
MISE_BIN should have a parent directory
What it means
On Windows self-update, mise writes `mise-shim.exe` next to the running binary using `env::MISE_BIN.parent()`. If `MISE_BIN` is a bare filename with no parent directory component, `.parent()` returns `None` and this `.expect()` panics. It guards the assumption that `MISE_BIN` always holds a full path to the mise executable.
Source
Thrown at src/cli/self_update.rs:660
fs::write(&zip_path, archive)?;
// Verify the archive signature using the same key as the main update
Self::verify_zip_signature(&zip_path)?;
let file = fs::File::open(&zip_path)?;
let mut archive = zip::ZipArchive::new(file)?;
let mut shim_entry = match archive.by_name("mise/bin/mise-shim.exe") {
Ok(entry) => entry,
Err(_) => {
warn!("mise-shim.exe not found in release archive, skipping");
return Ok(());
}
};
let dest = env::MISE_BIN
.parent()
.expect("MISE_BIN should have a parent directory")
.join("mise-shim.exe");
// Write to a temp file first, then rename for atomic replacement
let mut buf = Vec::new();
shim_entry.read_to_end(&mut buf)?;
let temp_shim = temp_dir.path().join("mise-shim.exe");
fs::write(&temp_shim, &buf)?;
if fs::rename(&temp_shim, &dest).is_err() {
// Fallback for cross-filesystem moves
fs::copy(&temp_shim, &dest)?;
}
debug!("Updated mise-shim.exe at {}", dest.display());
Ok(())
}
#[cfg(windows)]
fn verify_zip_signature(path: &std::path::Path) -> Result<()> {View on GitHub (pinned to afd2eddd3a)
Solutions
- Unset the custom `MISE_BIN` override (or set it to the full path, e.g. `MISE_BIN=C:\\Users\\you\\.local\\bin\\mise.exe`) and retry `mise self-update`
- Verify with `echo $MISE_BIN` that it contains a directory separator
- Locate the real binary with `which mise` (or `Get-Command mise`) and use that absolute path
- Update mise by your package manager instead of `mise self-update` to avoid the shim rewrite entirely
Example fix
// before (shell) export MISE_BIN=mise // after export MISE_BIN="$(which mise)"
Defensive patterns
Strategy: validation
Validate before calling
# Before running `mise self-update` on Windows: if [ -n "$MISE_BIN" ] && [[ "$MISE_BIN" != */* ]]; then export MISE_BIN="$(command -v mise)" fi mise self-update
Type guard
# PowerShell
if ($env:MISE_BIN -and -not $env:MISE_BIN.Contains([IO.Path]::DirectorySeparatorChar)) {
$env:MISE_BIN = (Get-Command mise).Source
} Prevention
- Never set MISE_BIN to a bare executable name
- Let mise set MISE_BIN itself; avoid overriding it in shell profiles
- Prefer package-manager updates over self-update when a wrapper manages the binary
When it happens
Trigger: `MISE_BIN` env var set to a bare name like `mise` instead of an absolute/relative path with a directory (e.g. `MISE_BIN=mise` rather than `MISE_BIN=C:\\bin\\mise.exe`); running `mise self-update` through a wrapper that overrides `MISE_BIN` incorrectly.
Common situations: Users who manually export `MISE_BIN` in their shell profile with just the executable name; launcher scripts or package managers setting `MISE_BIN` to something found via PATH lookup without a directory component.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Unknown shim mode
- TEMP is too long to replace mise.exe safely ({len} UTF-16 co
- failed to create file symlink: {err}
- {msg}
- command wrapper names cannot contain dots on Windows: {name:
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/3b4133898afba203.
Report an issue: GitHub.