jdx/mise · error

present bootstrap user '{name}' must not set remove_home

Error message

present bootstrap user '{name}' must not set remove_home

What it means

UserRequest::from_toml rejects a state = "present" user that sets remove_home = true. remove_home only applies to deletion (state = "absent"); combining it with a present user is contradictory — it would declare intent to both create/keep the account and delete its home directory — so parsing fails immediately with the user's name.

Source

Thrown at src/system/accounts.rs:336

            ResourceAction::Update => Ok(Some(AccountAction::UpdateGroup {
                name: self.name.clone(),
                gid: self.gid.expect("group update requires a desired gid"),
            })),
            ResourceAction::Remove => Ok(Some(AccountAction::RemoveGroup {
                name: self.name.clone(),
            })),
        }
    }
}

impl UserRequest {
    fn from_toml(name: String, config: UserTomlConfig) -> Result<Self> {
        validate_name("user", &name)?;
        if config.state == AccountState::Present && config.group.is_none() {
            bail!("present bootstrap user '{name}' requires a primary group");
        }
        if config.state == AccountState::Present && config.remove_home {
            bail!("present bootstrap user '{name}' must not set remove_home");
        }
        if config.state == AccountState::Absent
            && (config.uid.is_some()
                || config.group.is_some()
                || config.groups.is_some()
                || config.exclusive_groups
                || config.home.is_some()
                || config.shell.is_some()
                || config.comment.is_some()
                || config.system
                || config.create_home.is_some()
                || config.move_home)
        {
            bail!("absent bootstrap user '{name}' may only set state and remove_home");
        }
        if config.exclusive_groups && config.groups.is_none() {
            bail!("bootstrap user '{name}' sets exclusive_groups without groups");
        }

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Delete remove_home from the present user entry.
  2. If you really want the home directory gone while keeping the user, that is not supported by bootstrap — manage it outside mise.
  3. If the user should be removed, use state = "absent" where remove_home is valid.

Example fix

# before
[bootstrap.users.temp]
state = "present"
group = "users"
remove_home = true
# after
[bootstrap.users.temp]
state = "present"
group = "users"
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'EOF'
import sys, tomllib
cfg = tomllib.load(open('mise.toml','rb'))
for name, u in cfg.get('bootstrap', {}).get('users', {}).items():
    if u.get('state') == 'present' and u.get('remove_home'):
        sys.exit(f"present user '{name}' must not set remove_home")
EOF

Type guard

def present_user_clean(u: dict) -> bool:
    return not u.get('remove_home') if u.get('state') == 'present' else True

Prevention

When it happens

Trigger: A [bootstrap.users.<name>] table containing both state = "present" and remove_home = true, read while building account requests for `mise bootstrap plan`/`apply`.

Common situations: Flipping a user from absent (with remove_home = true) to present without cleaning up; copy-paste from a teardown config into a provisioning one.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


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