{"record":{"id":"dfd7b1d8de8b250c","repo":"larksuite/cli","slug":"invalid-profile-name-q-contains-control-characte","errorCode":null,"errorMessage":"invalid profile name %q: contains control characters","messagePattern":"invalid profile name %q: contains control characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/core/config.go","lineNumber":170,"sourceCode":"\tfor i := range m.Apps {\n\t\tnames[i] = m.Apps[i].ProfileName()\n\t}\n\treturn names\n}\n\n// ValidateProfileName checks that a profile name is valid.\n// Rejects empty names, whitespace, control characters, and shell-problematic characters,\n// but allows Unicode letters (e.g. Chinese, Japanese) for localized profile names.\nfunc ValidateProfileName(name string) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"profile name cannot be empty\")\n\t}\n\tif utf8.RuneCountInString(name) > 64 {\n\t\treturn fmt.Errorf(\"profile name %q is too long (max 64 characters)\", name)\n\t}\n\tfor _, r := range name {\n\t\tif r <= 0x1F || r == 0x7F { // control characters\n\t\t\treturn fmt.Errorf(\"invalid profile name %q: contains control characters\", name)\n\t\t}\n\t\tswitch r {\n\t\tcase ' ', '\\t', '/', '\\\\', '\"', '\\'', '`', '$', '#', '!', '&', '|', ';', '(', ')', '{', '}', '[', ']', '<', '>', '?', '*', '~':\n\t\t\treturn fmt.Errorf(\"invalid profile name %q: contains invalid character %q\", name, r)\n\t\t}\n\t}\n\treturn nil\n}\n\n// CliConfig is the resolved single-app config used by downstream code.\ntype CliConfig struct {\n\tProfileName         string\n\tAppID               string\n\tAppSecret           string\n\tBrand               LarkBrand\n\tDefaultAs           Identity // AsUser | AsBot | AsAuto | \"\" (from config file)\n\tUserOpenId          string\n\tUserName            string","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/core/config.go#L152-L188","documentation":"ValidateProfileName scans each rune and rejects control characters (0x1F and below or the equivalent class), which cannot be typed safely into shells or stored reliably - while Unicode letters remain allowed.","triggerScenarios":"A name containing newlines, tabs-embedded control bytes, ANSI escapes, or a lone DEL character reaches ValidateProfileName via auth init/add/rename.","commonSituations":"Copy-pasting a name with a trailing newline from a terminal; programmatically building names from raw API strings containing escape sequences; bad shell interpolation inserting CR (\\r) on Windows.","solutions":["Strip control characters before passing the name: trim whitespace and remove \\x00-\\x1F and \\x7F","Fix the source string (e.g. strings.TrimRight(name, \"\\r\\n\")) where the name is produced","Choose a simple printable ASCII or Unicode-letter name"],"exampleFix":"// before\nname := strings.TrimSpace(rawName)\n// after\nname := strings.Map(func(r rune) rune {\n    if r <= 0x1F || r == 0x7F { return -1 }\n    return r\n}, strings.TrimSpace(rawName))","handlingStrategy":"validation","validationCode":"func sanitizeProfileName(s string) string {\n    return strings.Map(func(r rune) rune {\n        if r <= 0x1F || r == 0x7F { return -1 }\n        return r\n    }, strings.TrimSpace(s))\n}","typeGuard":null,"tryCatchPattern":"if err := core.ValidateProfileName(name); err != nil {\n    if strings.Contains(err.Error(), \"control characters\") {\n        return fmt.Errorf(\"re-check where the name came from (clipboard/paste); %w\", err)\n    }\n    return err\n}","preventionTips":["Trim trailing newlines when reading names from stdin or files","Avoid embedding names from raw API responses without sanitization","Prefer simple letter/digit names"],"tags":["go","validation","control-characters"],"backgroundTag":"invalid-profile-name-characters","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}