jdx/mise · error

bootstrap user '{name}' {field} must be an absolute path

Error message

bootstrap user '{name}' {field} must be an absolute path

What it means

mise validates the `home` and `shell` fields of every `[bootstrap.users.<name>]` entry via `validate_account_path` before planning account changes. These values are handed verbatim to `useradd`/`usermod` and land in `/etc/passwd`, where both fields must be absolute paths, so a relative path is rejected at config-parse time. The failing project name and field are included in the message.

Source

Thrown at src/system/accounts.rs:727

            .next()
            .is_some_and(|character| character == '_' || character.is_ascii_alphabetic())
        && characters.all(|character| {
            character == '_'
                || character == '-'
                || character.is_ascii_digit()
                || character.is_ascii_alphabetic()
        });
    if !valid {
        bail!(
            "invalid bootstrap {kind} name '{name}': use at most 32 ASCII letters, digits, '_' or '-', with an optional trailing '$'"
        );
    }
    Ok(())
}

fn validate_account_path(name: &str, field: &str, path: &std::path::Path) -> Result<()> {
    if !path.is_absolute() {
        bail!("bootstrap user '{name}' {field} must be an absolute path");
    }
    if path
        .to_string_lossy()
        .chars()
        .any(|character| character == ':' || character == '\n' || character == '\r')
    {
        bail!("bootstrap user '{name}' {field} must not contain ':', CR, or LF");
    }
    Ok(())
}

pub fn plans(requests: &AccountRequests) -> Vec<ResourcePlan> {
    requests
        .groups
        .iter()
        .map(GroupRequest::plan)
        .chain(requests.users.iter().map(UserRequest::plan))
        .collect()

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Change the value to a path rooted at `/`, e.g. `home = "/home/mise"` or `shell = "/usr/bin/bash"`.
  2. If the home must live under a project, write the full absolute location such as `home = "/srv/myapp/home"`; `~` and relative paths are never expanded for account fields.
  3. Re-run `mise bootstrap accounts status` to confirm the config now parses and shows the planned state.

Example fix

# before
[bootstrap.users.deploy]
group = "deploy"
home = "srv/deploy"
shell = "bin/bash"

# after
[bootstrap.users.deploy]
group = "deploy"
home = "/srv/deploy"
shell = "/bin/bash"
Defensive patterns

Strategy: validation

Validate before calling

fn account_path_ok(p: &std::path::Path) -> bool {
    p.is_absolute()
        && !p.to_string_lossy().chars().any(|c| c == ':' || c.is_control())
}

// preflight over parsed config before calling accounts::apply
for (name, user) in &users {
    for (field, path) in [("home", &user.home), ("shell", &user.shell)] {
        if let Some(p) = path {
            assert!(account_path_ok(p), "{name} {field} must be absolute, no ':' or control chars");
        }
    }
}

Prevention

When it happens

Trigger: A `[bootstrap.users.<name>]` table sets `home = "app/data"`, `shell = "bin/bash"`, `home = "~/mise"`, or any value whose `Path::is_absolute()` is false. `UserRequest::from_toml` calls `validate_account_path(&name, "home"|"shell", path)` and bails as soon as `mise bootstrap accounts apply`/`status` reads the config.

Common situations: Copying docker-compose-style relative path conventions into bootstrap config; using `~` or `./` prefixes that mise deliberately does not expand here; pointing the home directory inside the project repo without spelling out the full path.

Related errors


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