jdx/mise · error
refusing unsafe change to bootstrap user '{}'; inspect `mise
Error message
refusing unsafe change to bootstrap user '{}'; inspect `mise bootstrap plan` What it means
UserRequest::action() turns the computed plan into an action; if the plan is ResourceAction::Unknown — the inspected current user state cannot be reconciled with the desired state safely (e.g. desired uid is already taken by another user, or inspected fields conflict in a way with no safe usermod transition) — mise refuses to perform any privileged change and points you at `mise bootstrap plan` for the details. Same deliberate safety stop as the group variant.
Source
Thrown at src/system/accounts.rs:546
groups.iter().cloned().collect::<Vec<_>>().join(",")
));
}
if let Some(home) = &self.home {
parts.push(format!("home {}", home.display()));
}
if let Some(shell) = &self.shell {
parts.push(format!("shell {}", shell.display()));
}
if let Some(comment) = &self.comment {
parts.push(format!("comment {comment}"));
}
parts.join("; ")
}
fn action(&self) -> Result<Option<AccountAction>> {
match self.plan().action {
ResourceAction::Noop => Ok(None),
ResourceAction::Unknown => bail!(
"refusing unsafe change to bootstrap user '{}'; inspect `mise bootstrap plan`",
self.name
),
ResourceAction::Create => Ok(Some(AccountAction::CreateUser {
name: self.name.clone(),
uid: self.uid,
group: self
.group
.clone()
.expect("present user has a primary group"),
groups: self
.groups
.as_ref()
.map(|groups| groups.iter().cloned().collect())
.unwrap_or_default(),
home: self.home.clone(),
shell: self.shell.clone(),
comment: self.comment.clone(),View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Run `mise bootstrap plan` and read the diff for the named user.
- Resolve uid conflicts: pick a free uid in config, or re-uid/remove the conflicting user manually first.
- Align or drop conflicting fields (home/shell/groups) until the plan shows create/update/remove instead of Unknown.
- Only then run `mise bootstrap apply`.
Example fix
# before: uid 1100 already owned by user 'oldci' [bootstrap.users.ci] state = "present" group = "ci" uid = 1100 # after [bootstrap.users.ci] state = "present" group = "ci" uid = 1150
Defensive patterns
Strategy: validation
Validate before calling
# gate apply on a clean plan out=$(mise bootstrap plan) if grep -q 'refusing unsafe change' <<<"$out"; then echo "$out" >&2; exit 1 fi mise bootstrap apply
Try / catch
Hard stop on this bail: parse the user name from the message, run `mise bootstrap plan`, resolve the uid/state collision (pick a free uid or reconcile the user manually), then re-plan. Never auto-retry apply unchanged.
Prevention
- Require `mise bootstrap plan` to pass (no Unknown actions) before apply in automation.
- Assign uids from a dedicated range and record them to avoid collisions.
- After manual account surgery on a host, re-run plan to resync expectations.
When it happens
Trigger: Bootstrap apply where a user's plan resolves to Unknown: uid collisions (desired uid owned by a different username), drifted home/shell/uid state that fits no safe transition, or login-name conflicts. `mise bootstrap plan` shows the Unknown action and the current-vs-desired diff for the named user.
Common situations: Reusing a uid from a removed service account; importing servers whose users drifted from the declared config; uid renumbering during consolidation; running apply on a host never inspected with plan first.
Related errors
- refusing unsafe change to bootstrap group '{}'; inspect `mis
- bootstrap plan contains resources with unknown state
- present bootstrap user '{name}' requires a primary group
- present bootstrap user '{name}' must not set remove_home
- absent bootstrap user '{name}' may only set state and remove
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/eee6d32e28fd8a06.
Report an issue: GitHub.