{"record":{"id":"e300c62f71aeaa9b","repo":"jdx/mise","slug":"bootstrap-user-name-comment-must-not-contain","errorCode":null,"errorMessage":"bootstrap user '{name}' comment must not contain ':', CR, or LF","messagePattern":"bootstrap user '(.+?)' comment must not contain ':', CR, or LF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/accounts.rs","lineNumber":372,"sourceCode":"        }\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\n            .as_ref()\n            .is_some_and(|comment| comment.contains([':', '\\n', '\\r']))\n        {\n            bail!(\"bootstrap user '{name}' comment must not contain ':', CR, or LF\");\n        }\n        let mut groups = config\n            .groups\n            .map(|groups| {\n                groups\n                    .into_iter()\n                    .map(|group| {\n                        validate_name(\"group\", &group)?;\n                        Ok(group)\n                    })\n                    .collect::<Result<BTreeSet<_>>>()\n            })\n            .transpose()?;\n        if let (Some(groups), Some(primary_group)) = (&mut groups, &config.group) {\n            groups.remove(primary_group);\n        }\n        let inspection = inspect_user(&name, config.uid)?;\n        Ok(Self {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/accounts.rs#L354-L390","documentation":"UserRequest::from_toml validates the GECOS comment field: it must not contain ':', CR (\\r), or LF (\\n). The comment is written to the colon-delimited /etc/passwd GECOS field, where ':' would shift subsequent fields and newlines would corrupt the passwd database; parsing fails with the user's name instead of producing a broken account file.","triggerScenarios":"A [bootstrap.users.<name>] entry whose comment = \"...\" value contains a colon (e.g. comment = \"CI user: build agents\") or an embedded newline from a multi-line TOML string, loaded during bootstrap parsing.","commonSituations":"Free-text descriptions with colons; comments copied from /etc/passwd-style strings that already include fields like 'Work Phone:'; multi-line TOML literals in generated configs.","solutions":["Replace ':' with '-' or ';' in the comment (e.g. \"CI user - build agents\").","Strip CR/LF: keep the comment a single line.","If you need structured contact data, encode it without delimiters (e.g. 'build (x1234)') following GECOS conventions."],"exampleFix":"# before\n[bootstrap.users.ci]\nstate = \"present\"\ngroup = \"ci\"\ncomment = \"CI user: build agents\"\n# after\n[bootstrap.users.ci]\nstate = \"present\"\ngroup = \"ci\"\ncomment = \"CI user - build agents\"","handlingStrategy":"type-guard","validationCode":"python3 - <<'EOF'\nimport sys, tomllib\ncfg = tomllib.load(open('mise.toml','rb'))\nfor name, u in cfg.get('bootstrap', {}).get('users', {}).items():\n    c = u.get('comment')\n    if c and any(ch in c for ch in ':\\r\\n'):\n        sys.exit(f\"user '{name}' comment contains ':', CR, or LF\")\nEOF","typeGuard":"def valid_gecos_comment(c: str) -> bool:\n    return not any(ch in c for ch in ':\\r\\n')","tryCatchPattern":null,"preventionTips":["Use '-' or ';' instead of ':' in account comments.","Keep comments to a single line; strip newlines in any config generator.","Remember the comment lands in the colon-delimited /etc/passwd GECOS field."],"tags":["mise","bootstrap","users","gecos","config-validation","passwd"],"backgroundTag":"config-validation-failed","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}