{"record":{"id":"3b4133898afba203","repo":"jdx/mise","slug":"mise-bin-should-have-a-parent-directory","errorCode":null,"errorMessage":"MISE_BIN should have a parent directory","messagePattern":"MISE_BIN should have a parent directory","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/self_update.rs","lineNumber":660,"sourceCode":"        fs::write(&zip_path, archive)?;\n\n        // Verify the archive signature using the same key as the main update\n        Self::verify_zip_signature(&zip_path)?;\n\n        let file = fs::File::open(&zip_path)?;\n        let mut archive = zip::ZipArchive::new(file)?;\n\n        let mut shim_entry = match archive.by_name(\"mise/bin/mise-shim.exe\") {\n            Ok(entry) => entry,\n            Err(_) => {\n                warn!(\"mise-shim.exe not found in release archive, skipping\");\n                return Ok(());\n            }\n        };\n\n        let dest = env::MISE_BIN\n            .parent()\n            .expect(\"MISE_BIN should have a parent directory\")\n            .join(\"mise-shim.exe\");\n\n        // Write to a temp file first, then rename for atomic replacement\n        let mut buf = Vec::new();\n        shim_entry.read_to_end(&mut buf)?;\n        let temp_shim = temp_dir.path().join(\"mise-shim.exe\");\n        fs::write(&temp_shim, &buf)?;\n        if fs::rename(&temp_shim, &dest).is_err() {\n            // Fallback for cross-filesystem moves\n            fs::copy(&temp_shim, &dest)?;\n        }\n\n        debug!(\"Updated mise-shim.exe at {}\", dest.display());\n        Ok(())\n    }\n\n    #[cfg(windows)]\n    fn verify_zip_signature(path: &std::path::Path) -> Result<()> {","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/self_update.rs#L642-L678","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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"],"exampleFix":"// before (shell)\nexport MISE_BIN=mise\n// after\nexport MISE_BIN=\"$(which mise)\"","handlingStrategy":"validation","validationCode":"# Before running `mise self-update` on Windows:\nif [ -n \"$MISE_BIN\" ] && [[ \"$MISE_BIN\" != */* ]]; then\n  export MISE_BIN=\"$(command -v mise)\"\nfi\nmise self-update","typeGuard":"# PowerShell\nif ($env:MISE_BIN -and -not $env:MISE_BIN.Contains([IO.Path]::DirectorySeparatorChar)) {\n  $env:MISE_BIN = (Get-Command mise).Source\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","panic","windows","self-update","env-var"],"backgroundTag":"missing-env-var","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}