jdx/mise · error

absent bootstrap group '{name}' must not set gid or system

Error message

absent bootstrap group '{name}' must not set gid or system

What it means

GroupRequest::from_toml validates that a group declared state = "absent" does not also carry gid = <n> or system = true. Removal requests are name-only: specifying a gid or the system flag for a group you are deleting is contradictory (and gid/system only make sense for creation), so config parsing fails fast with the offending group's name in the message.

Source

Thrown at src/system/accounts.rs:202

        .map(|(name, config)| GroupRequest::from_toml(name, config))
        .collect::<Result<Vec<_>>>()?;
    let users = users
        .into_iter()
        .map(|(name, config)| UserRequest::from_toml(name, config))
        .collect::<Result<Vec<_>>>()?;
    validate_requests(&groups, &users)?;
    Ok(AccountRequests { groups, users })
}

pub fn prepare_requests_from_config(config: &Config) -> Result<AccountRequests> {
    requests_from_config(config)
}

impl GroupRequest {
    fn from_toml(name: String, config: GroupTomlConfig) -> Result<Self> {
        validate_name("group", &name)?;
        if config.state == AccountState::Absent && (config.gid.is_some() || config.system) {
            bail!("absent bootstrap group '{name}' must not set gid or system");
        }
        let inspection = match nix::unistd::Group::from_name(&name)? {
            Some(group) => {
                let gid = group.gid.as_raw();
                let desired_gid_owner = match config.gid.filter(|desired| *desired != gid) {
                    Some(desired) => {
                        nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(desired))?
                            .map(|group| group.name)
                    }
                    None => None,
                };
                GroupInspection::Present {
                    gid,
                    desired_gid_owner,
                }
            }
            None => match config.gid {
                Some(gid) => match nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(gid))? {

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Reduce the absent group entry to state = "absent" only.
  2. If you meant to keep the group, set state = "present" and keep gid/system.
  3. Re-run `mise bootstrap plan` to confirm the config now parses.

Example fix

# before
[bootstrap.groups.legacy]
state = "absent"
gid = 1005
system = true
# after
[bootstrap.groups.legacy]
state = "absent"
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'EOF'
import sys, tomllib
cfg = tomllib.load(open('mise.toml','rb'))
for name, g in cfg.get('bootstrap', {}).get('groups', {}).items():
    if g.get('state') == 'absent' and ('gid' in g or g.get('system')):
        sys.exit(f"absent group '{name}' must not set gid or system")
EOF

Type guard

def absent_group_is_clean(g: dict) -> bool:
    return not ('gid' in g or g.get('system')) if g.get('state') == 'absent' else True

Prevention

When it happens

Trigger: A mise.toml [bootstrap.groups.<name>] table containing state = "absent" together with gid = 1005 and/or system = true, loaded by `mise bootstrap plan`/`apply` (or any account-request build).

Common situations: Flipping a group from present to absent and leaving the old creation fields behind; copy-pasting a present-group template and only changing state; attempting to 'delete by gid' which mise does not support.

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/2a58dc0ea0368e13. Report an issue: GitHub.