remotion-dev/remotion · error · TypeError
"colors" must be an array with at least 2 colors, but got ${
Error message
"colors" must be an array with at least 2 colors, but got ${JSON.stringify(colors)} What it means
Thrown by the `rings()` effect when `colors` is supplied but is not an array, or is an array with fewer than 2 entries. The effect cycles colors across concentric rings, so a single color would make every ring identical and is treated as a configuration error. `undefined` is allowed (defaults to `['#dff4ff', '#7cc6ff']`); only a present-but-invalid value throws.
Source
Thrown at packages/effects/src/rings.ts:162
);
}
};
const validateNonNegative = (value: number, name: string): void => {
if (value < 0) {
throw new TypeError(
`"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)}`,
);
}
};
const validateColors = (colors: unknown): void => {
if (colors === undefined) {
return;
}
if (!Array.isArray(colors) || colors.length < 2) {
throw new TypeError(
`"colors" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`,
);
}
for (let i = 0; i < colors.length; i++) {
assertRequiredColor(colors[i], `colors[${i}]`);
}
};
const assertOptionalCenter = (value: unknown, name: string): void => {
if (value === undefined) {
return;
}
if (
!Array.isArray(value) ||
value.length !== 2 ||
value.some((item) => typeof item !== 'number' || !Number.isFinite(item))View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Provide at least two color strings, e.g. `colors: ['#dff4ff', '#7cc6ff']`.
- Omit `colors` entirely to accept the default two-color palette.
- When building the array dynamically, guard with `if (palette.length >= 2) rings({colors: palette}); else rings({});`.
Example fix
// before
rings({colors: data.map((d) => d.color)});
// after
const palette = data.map((d) => d.color);
rings({colors: palette.length >= 2 ? palette : undefined}); Defensive patterns
Strategy: validation
Validate before calling
const validateRingsColors = (colors: unknown): string[] | undefined => {
if (colors === undefined) return undefined;
if (!Array.isArray(colors) || colors.length < 2 ||
colors.some((c) => typeof c !== 'string' || c.length === 0)) {
throw new TypeError('colors must be an array of >= 2 non-empty strings');
}
return colors as string[];
};
rings({colors: validateRingsColors(maybeColors)}); Type guard
const isRingsColors = (v: unknown): v is string[] => Array.isArray(v) && v.length >= 2 && v.every((c) => typeof c === 'string' && c.length > 0);
Prevention
- Build palette arrays from data with a length check before passing them in.
- Provide a fallback palette constant when dynamic data may collapse below 2 entries.
- Omit `colors` to accept the default rather than risking an invalid array.
When it happens
Trigger: Call `rings({colors: ['#dff4ff']})` (one entry), `rings({colors: []})`, `rings({colors: 'red'})`, or `rings({colors: ['#fff', '']})` (the empty string is later rejected by `assertRequiredColor`). Also hit when a dynamically-built palette array is filtered down to fewer than 2 items at runtime.
Common situations: Building the palette from data that may collapse to one element (e.g. `colors: data.map(d => d.color)` where `data` is short); spreading a user-supplied array without a length check; passing a CSS color string instead of an array of strings.
Related errors
- "colors" must be an array with at least 2 colors, but got ${
- "${name}" must be greater than or equal to 0, but got ${JSON
- "${name}" must be a [number, number] tuple
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be greater than or equal to 0, but got ${JSON
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/638047f2df419d81.
Report an issue: GitHub.