{"record":{"id":"aca3ca11a9dfece7","repo":"remotion-dev/remotion","slug":"colors-must-be-an-array-with-at-least-2-colors","errorCode":null,"errorMessage":"\"colors\" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}","messagePattern":"\"colors\" must be an array with at least 2 colors, but got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/checkerboard.ts","lineNumber":168,"sourceCode":"\t\t);\n\t}\n};\n\nconst validateNonNegative = (value: number, name: string): void => {\n\tif (value < 0) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than or equal to 0, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateColors = (colors: unknown): void => {\n\tif (colors === undefined) {\n\t\treturn;\n\t}\n\n\tif (!Array.isArray(colors) || colors.length < 2) {\n\t\tthrow new TypeError(\n\t\t\t`\"colors\" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`,\n\t\t);\n\t}\n\n\tfor (let i = 0; i < colors.length; i++) {\n\t\tassertRequiredColor(colors[i], `colors[${i}]`);\n\t}\n};\n\nconst validateCheckerboardParams = (params: CheckerboardParams): void => {\n\tassertEffectParamsObject(params, 'Checkerboard');\n\tvalidateColors(params.colors);\n\tassertOptionalFiniteNumber(params.cellSize, 'cellSize');\n\tassertOptionalFiniteNumber(params.gap, 'gap');\n\tassertOptionalFiniteNumber(params.angle, 'angle');\n\tassertOptionalFiniteNumber(params.offsetX, 'offsetX');\n\tassertOptionalFiniteNumber(params.offsetY, 'offsetY');\n\tassertOptionalBoolean(params.maskToSourceAlpha, 'maskToSourceAlpha');","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/checkerboard.ts#L150-L186","documentation":"Thrown by validateColors() during checkerboard validation when the colors prop is defined but is not an array of at least 2 entries. The checkerboard needs >= 2 colors to cycle through cells, so anything fewer is rejected as a TypeError before rendering. Each entry is then additionally validated as a color.","triggerScenarios":"Passing <Checkerboard colors={['#fff']} /> (single color), colors={null}, colors={'#fff,#000'} (a string instead of array), or colors={[]} (empty); validateColors() throws at checkerboard.ts:168.","commonSituations":"Passing a comma-separated string instead of an array, a data source returning one item, spreading an empty array, or forgetting the default and providing a single-element array.","solutions":["Provide at least two color strings: colors={['#dff4ff', '#7cc6ff']}.","If omitted entirely, the default two colors are used — simply remove the prop.","Coerce a delimited string to an array before passing: 'a,b'.split(',').","Validate dynamic data length before rendering and fall back to the default when fewer than 2 entries exist."],"exampleFix":"// before\n<Checkerboard colors={['#fff']} />\n\n// after\n<Checkerboard colors={['#dff4ff', '#7cc6ff']} />","handlingStrategy":"type-guard","validationCode":"const colors = rawColors ?? ['#dff4ff', '#7cc6ff'];\nif (!Array.isArray(colors) || colors.length < 2) {\n  throw new Error('Checkerboard colors must be an array with at least 2 entries');\n}\n// then: <Checkerboard colors={colors as readonly string[]} />","typeGuard":"const isColorArray = (v: unknown): v is readonly string[] =>\n  Array.isArray(v) && v.length >= 2 && v.every((c) => typeof c === 'string');","tryCatchPattern":null,"preventionTips":["Pass an array literal, never a comma-separated string.","For dynamic palettes, fall back to the default when fewer than 2 entries are available.","Use isColorArray to narrow external data before handing it to the effect."],"tags":["validation","checkerboard","effects","typescript","params","colors"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}