jdx/mise · error · eyre::Report

cannot determine the current user to own {}

Error message

cannot determine the current user to own {}

What it means

Creating or chowning the Homebrew prefix usually requires sudo, and afterwards ownership must be assigned to the invoking user (user:admin on macOS, just the user on Linux, matching brew's install.sh). mise resolves that user from the sudo environment; if it cannot determine one it aborts instead of guessing, because chowning to a wrong owner could lock the user out of the prefix.

Source

Thrown at src/system/packages/brew/prefix.rs:204

    let missing_subdirs: Vec<PathBuf> = dirs.iter().filter(|p| !p.exists()).cloned().collect();
    if !needs_create && !needs_chown && missing_subdirs.is_empty() {
        return Ok(());
    }
    // try without elevation first — covers prefixes under user-writable
    // parents; the real prefixes need sudo to create. Skipped under `sudo
    // mise`: root could create the dirs, but they must be chowned to the
    // invoking user afterwards
    if needs_create
        && !dry_run
        && sudo_invoking_user().is_none()
        && dirs.iter().try_for_each(std::fs::create_dir_all).is_ok()
    {
        return Ok(());
    }
    if needs_create || needs_chown {
        let Some(user) = prefix_owner() else {
            // never chown to a guessed owner — that can lock the user out
            bail!(
                "cannot determine the current user to own {}",
                prefix.display()
            );
        };
        // brew's install.sh chowns to user:admin on macOS, just the user on
        // Linux (the admin group doesn't exist there)
        let owner = if cfg!(target_os = "macos") {
            format!("{user}:admin")
        } else {
            user
        };
        let mut mkdir_dirs: Vec<String> = vec![prefix.to_string_lossy().to_string()];
        mkdir_dirs.extend(dirs.iter().map(|d| d.display().to_string()));
        let mkdir_args: Vec<String> = ["-p".to_string()].into_iter().chain(mkdir_dirs).collect();
        let chown_args: Vec<String> = vec!["-R".to_string(), owner, prefix.display().to_string()];
        if dry_run {
            miseprintln!("{}", sudo::argv("mkdir", &mkdir_args).join(" "));
            miseprintln!("{}", sudo::argv("chown", &chown_args).join(" "));

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Run `mise bootstrap packages apply` as a regular user with sudo available, so the invoking user is identifiable
  2. Ensure the running uid has a valid passwd entry and that SUDO_USER is preserved when escalating
  3. Pre-create the prefix manually, chown it to your user, and re-run so no ownership decision is needed
Defensive patterns

Strategy: validation

Validate before calling

# fail fast when ownership cannot be determined
if [ "$(id -u)" = 0 ] && [ -z "${SUDO_USER:-}" ]; then
    echo "running as root without SUDO_USER — brew prefix ownership is ambiguous"; exit 1
fi
getent passwd "$(id -un)" >/dev/null || { echo "no passwd entry for $(id -un)"; exit 1; }

Prevention

When it happens

Trigger: needs_create || needs_chown is true while prefix_owner() returns None — typically running as root without SUDO_USER set (bare docker exec as root), or the running uid having no matching passwd entry due to broken NSS/LDAP.

Common situations: Running mise in minimal containers as root without sudo; docker run with an arbitrary uid; LDAP/NSS misconfiguration so the invoking user cannot be looked up; CI jobs that drop environment variables including SUDO_USER.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/cdc5ebaa7a1328cc. Report an issue: GitHub.