{"record":{"id":"8df2f6056b5c0075","repo":"jdx/mise","slug":"bootstrap-user-name-field-must-not-contain","errorCode":null,"errorMessage":"bootstrap user '{name}' {field} must not contain ':', CR, or LF","messagePattern":"bootstrap user '(.+?)' (.+?) must not contain ':', CR, or LF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/accounts.rs","lineNumber":734,"sourceCode":"        });\n    if !valid {\n        bail!(\n            \"invalid bootstrap {kind} name '{name}': use at most 32 ASCII letters, digits, '_' or '-', with an optional trailing '$'\"\n        );\n    }\n    Ok(())\n}\n\nfn validate_account_path(name: &str, field: &str, path: &std::path::Path) -> Result<()> {\n    if !path.is_absolute() {\n        bail!(\"bootstrap user '{name}' {field} must be an absolute path\");\n    }\n    if path\n        .to_string_lossy()\n        .chars()\n        .any(|character| character == ':' || character == '\\n' || character == '\\r')\n    {\n        bail!(\"bootstrap user '{name}' {field} must not contain ':', CR, or LF\");\n    }\n    Ok(())\n}\n\npub fn plans(requests: &AccountRequests) -> Vec<ResourcePlan> {\n    requests\n        .groups\n        .iter()\n        .map(GroupRequest::plan)\n        .chain(requests.users.iter().map(UserRequest::plan))\n        .collect()\n}\n\npub fn apply(requests: &AccountRequests, dry_run: bool, yes: bool) -> Result<bool> {\n    let mut actions = vec![];\n    let mut unknown = vec![];\n    for group in requests\n        .groups","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/accounts.rs#L716-L752","documentation":"`validate_account_path` rejects `home`/`shell` paths containing `:`, CR, or LF. The colon is the field separator in `/etc/passwd`, and newlines would corrupt the account database (and the privileged JSON/stdin plan), so any such character in a user path is a config error. The check is done on the lossy string form of the path.","triggerScenarios":"A `[bootstrap.users.<name>]` entry sets `home = \"/home/a:b\"`, `shell = \"/bin/sh\\n\"`, or a path that picked up a carriage return (e.g. edited on Windows without newline normalization). `UserRequest::from_toml` bails during config parsing with the offending user name and field.","commonSituations":"Windows-authored mise.toml with CRLF line endings embedding `\\r` into quoted strings; creative home directory names containing colons; copy-paste from a spreadsheet or chat that introduced a line break inside the value.","solutions":["Remove `:`, CR, and LF characters from the `home`/`shell` value; use a plain absolute path like `/home/mise`.","If the file was edited on Windows, re-save with LF line endings (`.gitattributes` `* text=auto eol=lf` or editor setting) and re-check the quoted values.","Re-run `mise bootstrap accounts status` to confirm parsing succeeds."],"exampleFix":"# before\n[bootstrap.users.ci]\ngroup = \"ci\"\nhome = \"/home/ci:builder\"\n\n# after\n[bootstrap.users.ci]\ngroup = \"ci\"\nhome = \"/home/ci-builder\"","handlingStrategy":"validation","validationCode":"// reject ':' and control characters (CR/LF) before invoking accounts commands\nfn path_chars_ok(p: &std::path::Path) -> bool {\n    !p.to_string_lossy().chars().any(|c| c == ':' || c.is_control())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep mise.toml saved with LF line endings, especially when edited on Windows.","Never build home/shell paths by concatenating user-supplied strings that may contain ':' or newlines."],"tags":["mise","bootstrap","accounts","path-validation","illegal-characters","passwd"],"backgroundTag":"illegal-characters-in-path","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}