{"record":{"id":"ff14cdf1780330df","repo":"kovidgoyal/kitty","slug":"invalid-rgb-numbers","errorCode":null,"errorMessage":"invalid rgb numbers","messagePattern":"invalid rgb numbers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/utils/style/wrapper.go","lineNumber":157,"sourceCode":"\t} else {\n\t\tprefix = append(prefix, fmt.Sprintf(\"%d:2:%d:%d:%d\", number_base+8, self.val.Red, self.val.Green, self.val.Blue))\n\t}\n\treturn prefix, suffix\n}\n\ntype color_value struct {\n\tis_set bool\n\tval    color_type\n}\n\nfunc parse_sharp(color string) (ans RGBA, err error) {\n\tif len(color)%3 != 0 {\n\t\treturn RGBA{}, fmt.Errorf(\"length not a multiple of 3\")\n\t}\n\tpart_size := len(color) / 3\n\tr, g, b := color[:part_size], color[part_size:2*part_size], color[part_size*2:part_size*3]\n\tif !ans.parse_rgb_strings(r, g, b) {\n\t\terr = fmt.Errorf(\"invalid rgb numbers\")\n\t}\n\treturn\n}\n\nfunc parse_rgb(color string) (ans RGBA, err error) {\n\tcolors := strings.Split(color, \"/\")\n\tif len(colors) != 3 {\n\t\treturn RGBA{}, fmt.Errorf(\"length not a multiple of 3\")\n\t}\n\tif ans.parse_rgb_strings(colors[0], colors[1], colors[2]) {\n\t\treturn\n\t}\n\terr = fmt.Errorf(\"invalid rgb numbers\")\n\treturn\n}\n\nfunc parse_rgbi(color string) (ans RGBA, err error) {\n\tcolors := strings.Split(color, \"/\")","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/utils/style/wrapper.go#L139-L175","documentation":"Raised by parse_sharp after the hex string was successfully split into three equal parts, but at least one part failed to parse as a valid number via parse_rgb_strings. Each part is parsed as a hexadecimal component; non-hex characters (g-z, punctuation, spaces) cause failure. This indicates a structurally-balanced but numerically invalid hex color.","triggerScenarios":"ParseColor(\"#zz0000\") — length 6 splits into \"zz\",\"00\",\"00\", but 'z' is not a hex digit. Also strings like \"#1x2 3x4\" where whitespace or invalid characters end up inside the hex components after comment stripping/lowercasing.","commonSituations":"Typos in hex literals (using letters beyond f), pasting colors containing whitespace or unicode look-alike characters, or config values with embedded garbage that survives the comment-stripping logic.","solutions":["Ensure every character in the hex portion is 0-9 or a-f (after lowercasing).","Remove embedded whitespace/unicode characters from the color string.","Pre-validate with a regex such as ^#[0-9a-fA-F]+$ (with 3-divisible length) before calling ParseColor."],"exampleFix":"// before\ncol, err := style.ParseColor(\"#gg0000\") // 'g' is not a hex digit\n\n// after\ncol, err := style.ParseColor(\"#00gg00\".ReplaceAll) // no — use:\ncol, err := style.ParseColor(\"#0f0\") // valid short hex","handlingStrategy":"validation","validationCode":"func validHexDigits(s string) bool {\n\ts = strings.TrimPrefix(strings.TrimSpace(strings.ToLower(s)), \"#\")\n\tif len(s)%3 != 0 { return false }\n\tfor _, r := range s {\n\t\tif !(r >= '0' && r <= '9' || r >= 'a' && r <= 'f') { return false }\n\t}\n\treturn true\n}","typeGuard":"func isHexColor(s string) bool {\n\ts = strings.TrimPrefix(strings.ToLower(strings.TrimSpace(s)), \"#\")\n\treturn len(s) > 0 && len(s)%3 == 0 && strings.Trim(s, \"0123456789abcdef\") == \"\"\n}","tryCatchPattern":null,"preventionTips":["Strip whitespace and unicode artifacts from color strings.","Use a strict ^#[0-9a-f]{6}$ allow-list for user input.","Generate colors programmatically (fmt.Sprintf(\"#%02x%02x%02x\", r, g, b)) rather than hand-typing."],"tags":["color","hex-parse","invalid-characters","styling"],"backgroundTag":"color-parse-failed","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}