{"record":{"id":"dacca8eb6687c9b3","repo":"kovidgoyal/kitty","slug":"not-a-valid-color-name-v-w","errorCode":null,"errorMessage":"not a valid color name: %#v %w","messagePattern":"not a valid color name: %#v %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/utils/style/wrapper.go","lineNumber":240,"sourceCode":"\t\t}\n\tcase 'r':\n\t\tif len(raw) > 4 && strings.HasPrefix(raw, \"rgb\") {\n\t\t\traw = raw[3:]\n\t\t\tswitch raw[0] {\n\t\t\tcase ':':\n\t\t\t\tparser, raw = parse_rgb, raw[1:]\n\t\t\tcase 'i':\n\t\t\t\tif strings.HasPrefix(raw, \"i:\") {\n\t\t\t\t\tparser, raw = parse_rgbi, raw[2:]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif parser == nil {\n\t\terr = fmt.Errorf(\"not a valid color name: %#v\", color)\n\t} else {\n\t\tif ans, err = parser(raw); err != nil {\n\t\t\terr = fmt.Errorf(\"not a valid color name: %#v %w\", color, err)\n\t\t}\n\t}\n\treturn\n}\n\ntype NullableColor struct {\n\tColor RGBA\n\tIsSet bool\n}\n\nfunc ParseColorOrNone(color string) (NullableColor, error) {\n\traw := strings.TrimSpace(strings.ToLower(color))\n\tif raw == \"none\" {\n\t\treturn NullableColor{}, nil\n\t}\n\tc, err := ParseColor(raw)\n\treturn NullableColor{Color: c, IsSet: err == nil}, err\n}","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/utils/style/wrapper.go#L222-L258","documentation":"Raised by ParseColor when a structured parser WAS selected (hex or slash format) but that parser returned an error, which is then wrapped with the original input for context. The inner error is one of the length/number errors from parse_sharp, parse_rgb or parse_rgbi; this is the top-level wrapper a caller actually sees.","triggerScenarios":"Any of: ParseColor(\"#ff00\") (bad hex length), ParseColor(\"#gg0000\") (non-hex digits), a slash format with wrong part count or non-numeric/out-of-range parts. The wrapping preserves the cause via %w, so errors.Is/Unwrap can inspect it.","commonSituations":"User-facing color settings fields (set_color_in_color_map, ColorSettingsAsEscapeCodes, Set) receiving free-form text; config/theme files with slightly malformed values; the comment-stripping logic leaving a partially-valid string.","solutions":["Read the wrapped cause (err via errors.Unwrap) to identify whether it's a length or numeric problem, and fix the value accordingly.","Normalize color input to canonical #rrggbb hex before passing it in.","Wrap ParseColor calls and report both the offending value and the cause to the user/config layer.","Add a pre-validation regex/allow-list for user-supplied colors."],"exampleFix":"// before\nif _, err := style.ParseColor(userColor); err != nil {\n    return err // \"not a valid color name: \\\"#ff00\\\" length not a multiple of 3\"\n}\n\n// after\nvar hexRe = regexp.MustCompile(`^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$`)\nif !hexRe.MatchString(userColor) {\n    userColor = \"#ffffff\" // or reject with a clear message\n}\nif _, err := style.ParseColor(userColor); err != nil {\n    return fmt.Errorf(\"bad color %q: %w\", userColor, err)\n}","handlingStrategy":"try-catch","validationCode":"var colorRe = regexp.MustCompile(`^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$`)\n\nfunc sanitizeColor(s string) (string, bool) {\n\ts = strings.TrimSpace(strings.ToLower(s))\n\treturn s, colorRe.MatchString(s)\n}","typeGuard":"func isParseableColor(s string) bool {\n\ts = strings.TrimSpace(strings.ToLower(s))\n\tif _, ok := style.ColorNames[s]; ok { return true }\n\treturn strings.HasPrefix(s, \"#\") && len(s) > 1 && (len(s)-1)%3 == 0\n}","tryCatchPattern":"ans, err := style.ParseColor(input)\nif err != nil {\n\tvar cause error = errors.Unwrap(err) // inner length/number error\n\tlog.Printf(\"bad color %q (%v); falling back\", input, cause)\n\tans, err = style.ParseColor(\"#ffffff\")\n\tif err != nil { return err } // default must be valid\n}","preventionTips":["Centralize color parsing behind one helper with fallback.","Use errors.Unwrap/errors.Is to surface the root cause in logs.","Unit-test ParseColor with the exact values your config accepts."],"tags":["color","wrapped-error","validation","styling"],"backgroundTag":"color-parse-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}