jdx/mise · error

present bootstrap user

Error message

present bootstrap user '{name}' requires a primary group

What it means

A bootstrap user declared with state = "present" must name a primary group, because creating a Linux user requires knowing which group it belongs to; mise deliberately does not auto-create an implicit per-user group. from_toml validates this up front so misconfiguration fails before any system change.

Solutions

  1. Add the required group key to the user entry in mise.toml
  2. If the group does not exist yet, declare it first under [bootstrap.groups] so it is created before the user
  3. If the user should not exist, set state = "absent" instead, which does not require a group

Example fix

# before
[bootstrap.users]
app = { uid = 1500, system = true }

# after
[bootstrap.users]
app = { uid = 1500, system = true, group = "app" }
Defensive patterns

Strategy: validation

Validate before calling

# fail fast if any present bootstrap user lacks a group
tomlq -r '.bootstrap.users | to_entries[] | select((.value.state // "present") == "present") | select(has("group") | not) | .key' mise.toml

Prevention

When it happens

Trigger: [bootstrap.users] entry with state = "present" (the default) but no group = "..." key; copy-pasting a user stanza and dropping the group field; generating configs where group is omitted for absent-state users and the state is later flipped to present.

Common situations: First-time bootstrap setup where users are added without their service groups; refactoring user entries in mise.toml; docs examples showing absent-state users without group then being adapted to present.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/7c4ca4a8633ed5fd. Report an issue: GitHub.

Appendix: source

Thrown at src/system/accounts.rs:333

                gid: self.gid,
                system: self.system,
            })),
            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");
        }

View on GitHub (pinned to 533346cc37)