{"record":{"id":"8e89f13841b3c347","repo":"jdx/mise","slug":"absent-bootstrap-user-name-may-only-set-state","errorCode":null,"errorMessage":"absent bootstrap user '{name}' may only set state and remove_home","messagePattern":"absent bootstrap user '(.+?)' may only set state and remove_home","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/accounts.rs","lineNumber":350,"sourceCode":"        if config.state == AccountState::Present && config.group.is_none() {\n            bail!(\"present bootstrap user '{name}' requires a primary group\");\n        }\n        if config.state == AccountState::Present && config.remove_home {\n            bail!(\"present bootstrap user '{name}' must not set remove_home\");\n        }\n        if config.state == AccountState::Absent\n            && (config.uid.is_some()\n                || config.group.is_some()\n                || config.groups.is_some()\n                || config.exclusive_groups\n                || config.home.is_some()\n                || config.shell.is_some()\n                || config.comment.is_some()\n                || config.system\n                || config.create_home.is_some()\n                || config.move_home)\n        {\n            bail!(\"absent bootstrap user '{name}' may only set state and remove_home\");\n        }\n        if config.exclusive_groups && config.groups.is_none() {\n            bail!(\"bootstrap user '{name}' sets exclusive_groups without groups\");\n        }\n        if config.move_home && config.home.is_none() {\n            bail!(\"bootstrap user '{name}' sets move_home without home\");\n        }\n        if let Some(group) = &config.group {\n            validate_name(\"group\", group)?;\n        }\n        if let Some(path) = &config.home {\n            validate_account_path(&name, \"home\", path)?;\n        }\n        if let Some(path) = &config.shell {\n            validate_account_path(&name, \"shell\", path)?;\n        }\n        if config\n            .comment","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/accounts.rs#L332-L368","documentation":"When a bootstrap user is declared with state=absent, mise only allows configuring the user's state and remove_home; all other user attributes (shell, comment, uid/gid, groups, system, create_home, move_home, home, etc.) are rejected. This prevents silently configuring properties of a user that will not exist. The check runs during bootstrap plan validation in src/system/accounts.rs.","triggerScenarios":"Declaring a bootstrap user with state=\"absent\" while also setting any of: shell, comment, uid/gid, system=true, create_home, move_home, home, groups, or exclusive_groups.","commonSituations":"Reusing one TOML user block for both 'create this user' and 'remove that user' by only flipping state to absent; refactoring a previously-present user entry to absent without pruning its attribute fields; copy-pasting a present-user definition and adding state=\"absent\".","solutions":["Strip all attribute fields from the user entry, keeping only state (and remove_home if desired).","If you actually want the user configured, remove state=\"absent\" so the fields are meaningful.","Run `mise bootstrap plan` to confirm which fields triggered the rejection."],"exampleFix":"// before\n[[bootstrap.users]]\nname = \"svc\"\nstate = \"absent\"\nshell = \"/usr/sbin/nologin\"\ngroups = [\"docker\"]\n\n// after\n[[bootstrap.users]]\nname = \"svc\"\nstate = \"absent\"\nremove_home = true","handlingStrategy":"validation","validationCode":"function validateAbsentUser(user) {\n  const allowed = new Set(['name', 'state', 'remove_home']);\n  if (user.state === 'absent') {\n    const extra = Object.keys(user).filter((k) => !allowed.has(k));\n    if (extra.length) throw new Error(`absent user sets fields: ${extra.join(', ')}`);\n  }\n}","typeGuard":"function isAbsentOnlyUser(user) {\n  return user.state === 'absent' &&\n    Object.keys(user).every((k) => ['name', 'state', 'remove_home'].includes(k));\n}","tryCatchPattern":"try {\n  await mise.bootstrap.apply(config);\n} catch (e) {\n  if (String(e).includes(\"may only set state and remove_home\")) {\n    console.error('Prune attribute fields from absent-user entries:', e.message);\n  } else throw e;\n}","preventionTips":["Keep absent-user entries minimal: name, state, remove_home only.","Never reuse a single user block for both present and absent states — define separate entries.","Run `mise bootstrap plan` in CI before applying."],"tags":["bootstrap","user-management","config-validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}