{"record":{"id":"2a58dc0ea0368e13","repo":"jdx/mise","slug":"absent-bootstrap-group-name-must-not-set-gid-o","errorCode":null,"errorMessage":"absent bootstrap group '{name}' must not set gid or system","messagePattern":"absent bootstrap group '(.+?)' must not set gid or system","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/accounts.rs","lineNumber":202,"sourceCode":"        .map(|(name, config)| GroupRequest::from_toml(name, config))\n        .collect::<Result<Vec<_>>>()?;\n    let users = users\n        .into_iter()\n        .map(|(name, config)| UserRequest::from_toml(name, config))\n        .collect::<Result<Vec<_>>>()?;\n    validate_requests(&groups, &users)?;\n    Ok(AccountRequests { groups, users })\n}\n\npub(crate) fn prepare_requests_from_config(config: &Config) -> Result<AccountRequests> {\n    requests_from_config(config)\n}\n\nimpl GroupRequest {\n    fn from_toml(name: String, config: GroupTomlConfig) -> Result<Self> {\n        validate_name(\"group\", &name)?;\n        if config.state == AccountState::Absent && (config.gid.is_some() || config.system) {\n            bail!(\"absent bootstrap group '{name}' must not set gid or system\");\n        }\n        let inspection = match nix::unistd::Group::from_name(&name)? {\n            Some(group) => {\n                let gid = group.gid.as_raw();\n                let desired_gid_owner = match config.gid.filter(|desired| *desired != gid) {\n                    Some(desired) => {\n                        nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(desired))?\n                            .map(|group| group.name)\n                    }\n                    None => None,\n                };\n                GroupInspection::Present {\n                    gid,\n                    desired_gid_owner,\n                }\n            }\n            None => match config.gid {\n                Some(gid) => match nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(gid))? {","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/accounts.rs#L184-L220","documentation":"When a bootstrap group is declared with state = \"absent\", the group only needs its name — mise just removes it if it exists. Setting gid or system alongside \"absent\" is contradictory (there is no GID or system status for a group that should not exist), so from_toml rejects the config eagerly. This is a config-validation error raised before any system mutation.","triggerScenarios":"A [bootstrap.groups] entry with state = \"absent\" that also specifies gid = N or system = true; a config converted from \"present\" to \"absent\" without deleting the now-meaningless fields.","commonSituations":"Decommissioning a group: flipping state to absent but leaving gid/system in place; copy-pasting a present-group stanza and only changing state; template-generated configs where fields are always emitted.","solutions":["Remove the gid and system keys from the absent group entry in mise.toml","If you intended the group to exist, change state to \"present\" instead of removing the fields","Regenerate the entry from the mise bootstrap plan/docs schema to see valid fields for absent state"],"exampleFix":"# before\n[bootstrap.groups]\nlegacy-app = { state = \"absent\", gid = 1500, system = true }\n\n# after\n[bootstrap.groups]\nlegacy-app = { state = \"absent\" }","handlingStrategy":"validation","validationCode":"# validate all absent groups carry no gid/system before running mise\ntomlq -r '.bootstrap.groups | to_entries[] | select(.value.state == \"absent\") | select(has(\"gid\") or has(\"system\")) | .key' mise.toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat state = \"absent\" entries as name-only declarations","When flipping state to absent, delete obsolete fields in the same edit","Run `mise bootstrap plan` (dry-run) after editing bootstrap config to catch validation errors early","Add a CI lint that greps absent-state group entries for forbidden keys"],"tags":["config-validation","bootstrap","groups","toml"],"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"}