3b1b/manim · error · Exception
Invalid color type
Error message
Invalid color type
What it means
Raised by color_to_rgb (utils/color.py:28) when the color argument is neither a str (hex name like '#FF0000' or a color name handled by hex_to_rgb) nor a colour.Color instance. Any other type — tuple, list, np.ndarray, int — falls through to the generic error, since only those two representations are understood.
Source
Thrown at manimlib/utils/color.py:28
from manimlib.constants import COLORMAP_3B1B
from manimlib.constants import WHITE
from manimlib.utils.bezier import interpolate
from manimlib.utils.iterables import resize_with_interpolation
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Iterable, Sequence, Callable
from manimlib.typing import ManimColor, Vect3, Vect4, Vect3Array, Vect4Array, NDArray
def color_to_rgb(color: ManimColor) -> Vect3:
if isinstance(color, str):
return hex_to_rgb(color)
elif isinstance(color, Color):
return np.array(color.get_rgb())
else:
raise Exception("Invalid color type")
def color_to_rgba(color: ManimColor, alpha: float = 1.0) -> Vect4:
return np.array([*color_to_rgb(color), alpha])
def rgb_to_color(rgb: Vect3 | Sequence[float]) -> Color:
try:
return Color(rgb=tuple(rgb))
except ValueError:
return Color(WHITE)
def rgba_to_color(rgba: Vect4) -> Color:
return rgb_to_color(rgba[:3])
def rgb_to_hex(rgb: Vect3 | Sequence[float]) -> str:View on GitHub (pinned to dee01804d4)
Solutions
- Convert tuples/arrays to a colour.Color first: Color(rgb=tuple(rgb)) — note rgb_to_color does exactly this
- Use hex strings ('#RRGGBB') or named colors understood by the colour module
- Wrap untrusted color values: color if isinstance(color, (str, Color)) else Color(rgb=tuple(color))
Example fix
# before mob.set_fill(color=(1, 0, 0)) # tuple -> raises # after from colour import Color mob.set_fill(color=Color(rgb=(1, 0, 0)))
Defensive patterns
Strategy: type-guard
Validate before calling
from colour import Color
import numpy as np
def as_manim_color(c):
if isinstance(c, (str, Color)):
return c
return Color(rgb=tuple(np.array(c)[:3]))
mob.set_fill(color=as_manim_color(user_color)) Type guard
from colour import Color
def is_manim_color(c) -> bool:
return isinstance(c, (str, Color)) Prevention
- Normalize colors at your API boundary: str hex or Color only
- Convert RGB tuples with Color(rgb=tuple(...)) before passing to color APIs
- Keep scene color data as hex strings to avoid accidental tuple leakage
When it happens
Trigger: set_fill(color=(1, 0, 0)) or set_color(np.array([0.5, 0.5, 0.5])) raises; passing a QColor, a CSS 'rgb(...)' string, or an int 0xFF0000 also raises. Passing '#FF0000' or Color(rgb=(1,0,0)) works.
Common situations: Coming from other graphics libraries where RGB tuples are the norm; storing colors as numpy arrays in scene data; refactors that pass raw values from shaders/interpolations into color APIs.
Related errors
- Need at least one color
- At least 2 mobjects needed for Union.
- At least 2 mobjects needed for Intersection.
- At least 2 mobjects needed for Exclusion.
- Invalid input sample type
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/8a472a8f6b8262ad.
Report an issue: GitHub.