jdx/mise · error

refusing unsafe change to bootstrap group

Error message

refusing unsafe change to bootstrap group '{}'; inspect `mise bootstrap plan`

What it means

Before applying a change to a bootstrap group, mise computes a plan; if the plan's action is Unknown — meaning the current group state could not be inspected reliably enough to guarantee a safe change — mise refuses to proceed rather than guess. This protects against destructive or wrong modifications to system groups. The error tells you to inspect the outcome with `mise bootstrap plan`.

Solutions

  1. Run `mise bootstrap plan` and read the reported state/action for the group; reconcile the group manually (groupadd/groupmod/groupdel) so the plan becomes a known action (Create/Modify/Noop)
  2. Fix the underlying inspection problem (permissions on /etc/group, NSS configuration, duplicate group names)
  3. Align the mise.toml entry with the actual group state (correct gid/system/state) so the plan is unambiguous
  4. Re-run apply only after the plan shows a safe, non-Unknown action
Defensive patterns

Strategy: validation

Validate before calling

mise bootstrap plan   # must show a concrete Create/Modify/Noop action, never Unknown, before apply

Try / catch

# shell
if ! mise bootstrap plan 2>&1 | grep -q 'Unknown'; then
  mise bootstrap apply || exit 1
else
  echo "refusing: unsafe bootstrap plan; reconcile group state manually" >&2
  exit 1
fi

Prevention

When it happens

Trigger: Running `mise bootstrap apply` when the group's plan resolves to ResourceAction::Unknown, e.g. nix group inspection fails, the group exists with ambiguous state, or the system group database is inconsistent; running apply on a host where the group name cannot be resolved and the desired state cannot be verified.

Common situations: Corrupt or partially-managed /etc/group entries; the group was created outside mise with unexpected attributes; permission problems reading the group database; race where another tool deleted the group between plan and apply.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/system/accounts.rs:309

            ),
            (GroupInspection::IdCollision { gid, name }, AccountState::Present) => {
                ResourcePlan::new(
                    id,
                    format!("absent; gid {gid} belongs to {name}"),
                    desired,
                    ResourceAction::Unknown,
                )
            }
            (GroupInspection::IdCollision { .. }, AccountState::Absent) => {
                ResourcePlan::new(id, "absent", desired, ResourceAction::Noop)
            }
        }
    }

    fn action(&self) -> Result<Option<AccountAction>> {
        match self.plan().action {
            ResourceAction::Noop => Ok(None),
            ResourceAction::Unknown => bail!(
                "refusing unsafe change to bootstrap group '{}'; inspect `mise bootstrap plan`",
                self.name
            ),
            ResourceAction::Create => Ok(Some(AccountAction::CreateGroup {
                name: self.name.clone(),
                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(),
            })),
        }
    }
}

View on GitHub (pinned to 533346cc37)