{"record":{"id":"566f286d4dd58350","repo":"jdx/mise","slug":"only-available-on-unix","errorCode":null,"errorMessage":"only available on unix","messagePattern":"only available on unix","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/login_shell.rs","lineNumber":106,"sourceCode":"fn target_user() -> Result<nix::unistd::User> {\n    use eyre::eyre;\n    use nix::unistd::{User, geteuid};\n\n    if geteuid().is_root()\n        && let Ok(sudo_user) = crate::env::var(\"SUDO_USER\")\n        && !sudo_user.is_empty()\n        && sudo_user != \"root\"\n    {\n        return User::from_name(&sudo_user)?\n            .ok_or_else(|| eyre!(\"failed to find user from SUDO_USER={sudo_user}\"));\n    }\n    let uid = geteuid();\n    User::from_uid(uid)?.ok_or_else(|| eyre!(\"failed to find user for uid {uid}\"))\n}\n\n#[cfg(not(unix))]\nfn target_user() -> Result<TargetUser> {\n    eyre::bail!(\"{}\", unavailable_reason())\n}\n\n#[cfg(not(unix))]\nstruct TargetUser {\n    name: String,\n    shell: PathBuf,\n}\n\nfn display_shell(shell: PathBuf) -> String {\n    shell.to_string_lossy().to_string()\n}\n\n#[cfg(unix)]\nfn chsh_args(request: &LoginShellRequest, user: &nix::unistd::User) -> Vec<String> {\n    chsh_args_for_user_name(request, &user.name)\n}\n\n#[cfg(unix)]","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/login_shell.rs#L88-L124","documentation":"Parts of mise's system module resolve the invoking user (name, shell) from the Unix user database, honoring SUDO_USER for privilege drops. On non-Unix builds (Windows) that code is cfg'd out and target_user() immediately bails with unavailable_reason(), the literal message being 'only available on unix' (src/system/login_shell.rs:106). It is a hard platform gate: no fallback user lookup exists on Windows.","triggerScenarios":"Running a mise command/bootstrap flow that needs the login shell or target user (e.g. bootstrap phases that execute as the resolved user) on a Windows build of mise. The #[cfg(not(unix))] target_user is invoked and bails immediately.","commonSituations":"Windows machines running `mise bootstrap` with config that exercises unix-only subsystems; CI matrices including Windows against shared mise.toml files; trying user/privilege features on Windows where only a subset of bootstrap is supported.","solutions":["Run the affected flow on macOS/Linux/WSL, where the user database lookup exists","On Windows, remove or gate the config sections that require unix user resolution so they are not evaluated","Split shared config so unix-only bootstrap sections live in OS-specific files mise does not load on Windows"],"exampleFix":"# before (shared mise.toml used on Windows)\n[bootstrap.hooks.post-user]\nrun = \"./setup-user.sh\"\n\n# after: move unix-only sections to e.g. mise.macos.toml / mise.linux.toml\n# and keep the Windows-used mise.toml free of unix-user-dependent phases","handlingStrategy":"fallback","validationCode":"# gate unix-only bootstrap flows by OS before invoking them\nuname -s | grep -qE 'Darwin|Linux' || echo \"skip unix-only mise bootstrap flow on $(uname -s)\"","typeGuard":"import platform\ndef supports_unix_user_lookup() -> bool:\n    return platform.system() in (\"Linux\", \"Darwin\")","tryCatchPattern":null,"preventionTips":["Split config by OS (e.g. mise.macos.toml / mise.linux.toml) so Windows never evaluates unix-only sections","Treat 'only available on unix' as a platform gate, not a transient error — do not retry it","Run unix-dependent flows inside WSL on Windows machines"],"tags":["mise","windows","platform","unix","bootstrap"],"backgroundTag":"unix-only-feature","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}