{"record":{"id":"7c4ca4a8633ed5fd","repo":"jdx/mise","slug":"present-bootstrap-user-name-requires-a-primary","errorCode":null,"errorMessage":"present bootstrap user '{name}' requires a primary group","messagePattern":"present bootstrap user '(.+?)' requires a primary group","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/accounts.rs","lineNumber":333,"sourceCode":"                gid: self.gid,\n                system: self.system,\n            })),\n            ResourceAction::Update => Ok(Some(AccountAction::UpdateGroup {\n                name: self.name.clone(),\n                gid: self.gid.expect(\"group update requires a desired gid\"),\n            })),\n            ResourceAction::Remove => Ok(Some(AccountAction::RemoveGroup {\n                name: self.name.clone(),\n            })),\n        }\n    }\n}\n\nimpl UserRequest {\n    fn from_toml(name: String, config: UserTomlConfig) -> Result<Self> {\n        validate_name(\"user\", &name)?;\n        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        }","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/accounts.rs#L315-L351","documentation":"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.","triggerScenarios":"[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.","commonSituations":"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.","solutions":["Add the required group key to the user entry in mise.toml","If the group does not exist yet, declare it first under [bootstrap.groups] so it is created before the user","If the user should not exist, set state = \"absent\" instead, which does not require a group"],"exampleFix":"# before\n[bootstrap.users]\napp = { uid = 1500, system = true }\n\n# after\n[bootstrap.users]\napp = { uid = 1500, system = true, group = \"app\" }","handlingStrategy":"validation","validationCode":"# fail fast if any present bootstrap user lacks a group\ntomlq -r '.bootstrap.users | to_entries[] | select((.value.state // \"present\") == \"present\") | select(has(\"group\") | not) | .key' mise.toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always specify a primary group for present-state users; pair every [bootstrap.users] entry with a [bootstrap.groups] entry","Declare the group before the user so ordering is obvious in the config","Run `mise bootstrap plan` after editing user config to catch validation before apply","Add a CI check or schema validation for the bootstrap section"],"tags":["config-validation","bootstrap","users","toml"],"backgroundTag":"missing-required-config-field","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"}