{"record":{"id":"451ca48985455ca0","repo":"Textualize/rich","slug":"expected-three-components-in-original-color-r","errorCode":null,"errorMessage":"expected three components in {original_color!r}","messagePattern":"expected three components in (.+?)","errorType":"validation","errorClass":"ColorParseError","httpStatus":null,"severity":"error","filePath":"rich/color.py","lineNumber":473,"sourceCode":"            triplet = ColorTriplet(\n                int(color_24[0:2], 16), int(color_24[2:4], 16), int(color_24[4:6], 16)\n            )\n            return cls(color, ColorType.TRUECOLOR, triplet=triplet)\n\n        elif color_8:\n            number = int(color_8)\n            if number > 255:\n                raise ColorParseError(f\"color number must be <= 255 in {color!r}\")\n            return cls(\n                color,\n                type=(ColorType.STANDARD if number < 16 else ColorType.EIGHT_BIT),\n                number=number,\n            )\n\n        else:  #  color_rgb:\n            components = color_rgb.split(\",\")\n            if len(components) != 3:\n                raise ColorParseError(\n                    f\"expected three components in {original_color!r}\"\n                )\n            red, green, blue = components\n            triplet = ColorTriplet(int(red), int(green), int(blue))\n            if not all(component <= 255 for component in triplet):\n                raise ColorParseError(\n                    f\"color components must be <= 255 in {original_color!r}\"\n                )\n            return cls(color, ColorType.TRUECOLOR, triplet=triplet)\n\n    @lru_cache(maxsize=1024)\n    def get_ansi_codes(self, foreground: bool = True) -> Tuple[str, ...]:\n        \"\"\"Get the ANSI escape codes for this color.\"\"\"\n        _type = self.type\n        if _type == ColorType.DEFAULT:\n            return (\"39\" if foreground else \"49\",)\n\n        elif _type == ColorType.WINDOWS:","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/Textualize/rich/blob/9d8f9a372cc5916fd4781fec207ced7ddac2f08f/rich/color.py#L455-L491","documentation":"In the rgb(...) branch of Color.parse, the comma-separated payload must yield exactly three components (red, green, blue); otherwise ColorParseError(\"expected three components in ...\") is raised. The regex accepts a fairly loose \"r,g,b\" payload, so 1, 2, or 4+ components reach this check and fail there rather than in the regex.","triggerScenarios":"Color.parse(\"rgb(1,2)\") (missing blue); \"rgb(1,2,3,4)\" (four values, e.g. an RGBA string fed in verbatim); \"rgb(1,,3)\" (empty component); concatenating channels with the wrong separator count.","commonSituations":"Feeding CSS rgba() strings into rich (rich has no alpha in Color); building rgb strings by string formatting with an accidental extra/missing comma; copy-pasting colors from design tools that emit rgba or 4-component values.","solutions":["Supply exactly three comma-separated integers: rgb(red,green,blue)","Strip alpha before passing: convert rgba(r,g,b,a) to rgb(r,g,b)","Build the string from a fixed 3-tuple: f\"rgb({r},{g},{b})\""],"exampleFix":"// before (Python)\nColor.parse(\"rgb(255,0,0,0.5)\")  # ColorParseError: 4 components\n// after\nColor.parse(\"rgb(255,0,0)\")","handlingStrategy":"validation","validationCode":"parts = rgba_string.split(\",\")\nif len(parts) == 4:\n    parts = parts[:3]  # drop alpha\nassert len(parts) == 3, f\"need r,g,b, got {parts!r}\"\ncolor_str = f\"rgb({','.join(parts)})\"","typeGuard":"def is_three_component_rgb(s: str) -> bool:\n    parts = s.strip().removeprefix(\"rgb\").strip(\"() \").split(\",\")\n    return len(parts) == 3 and all(p.strip().isdigit() for p in parts)","tryCatchPattern":null,"preventionTips":["Strip alpha from rgba() values before passing to rich","Build rgb strings from a fixed 3-tuple instead of string concatenation","Remember rich Color has no alpha channel"],"tags":["python","rich","color","rgb","parsing","colorparseerror"],"backgroundTag":null,"analyzedSha":"9d8f9a372cc5916fd4781fec207ced7ddac2f08f","analyzedAt":"2026-08-15T03:30:11.781Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}