{"record":{"id":"696a701b5db83566","repo":"remotion-dev/remotion","slug":"name-must-be-a-number-number-tuple-696a70","errorCode":null,"errorMessage":"\"${name}\" must be a [number, number] tuple","messagePattern":"\"(.+?)\" must be a \\[number, number\\] tuple","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/rings.ts","lineNumber":182,"sourceCode":"\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 assertOptionalCenter = (value: unknown, name: string): void => {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (\n\t\t!Array.isArray(value) ||\n\t\tvalue.length !== 2 ||\n\t\tvalue.some((item) => typeof item !== 'number' || !Number.isFinite(item))\n\t) {\n\t\tthrow new TypeError(`\"${name}\" must be a [number, number] tuple`);\n\t}\n\n\tvalidateUnitInterval(value[0], `${name}[0]`);\n\tvalidateUnitInterval(value[1], `${name}[1]`);\n};\n\nconst validateRingsParams = (params: RingsParams): void => {\n\tassertEffectParamsObject(params, 'Rings');\n\tvalidateColors(params.colors);\n\tassertOptionalCenter(params.center, 'center');\n\tassertOptionalFiniteNumber(params.thickness, 'thickness');\n\tassertOptionalFiniteNumber(params.gap, 'gap');\n\tassertOptionalFiniteNumber(params.offset, 'offset');\n\tassertOptionalBoolean(params.maskToSourceAlpha, 'maskToSourceAlpha');\n\n\tconst thickness = params.thickness ?? DEFAULT_THICKNESS;\n\tconst gap = params.gap ?? DEFAULT_GAP;\n\tvalidatePositive(thickness, 'thickness');","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/rings.ts#L164-L200","documentation":"Thrown by the `rings()` effect when `center` is supplied but is not a `[number, number]` tuple of finite numbers. `center` is the ring origin in normalized UV coordinates (each component later constrained to [0,1] by `validateUnitInterval`). The validator requires a two-element array where every element is a finite number; anything else (wrong length, strings, `NaN`, objects) is rejected.","triggerScenarios":"Call `rings({center: [0.5]})`, `rings({center: [0.5, 0.5, 0]})`, `rings({center: {x: 0.5, y: 0.5}})`, `rings({center: ['0.5', '0.5']})`, or `rings({center: [0.5, Number.NaN]})`. Each component is also range-checked, so `center: [1.5, 0.5]` will instead throw the `validateUnitInterval` `\">= 0\"` / `\"<= 1\"` error on `center[0]`.","commonSituations":"Passing an `{x, y}` point object from a drag handler instead of a tuple; reading center from JSON where numbers became strings; reusing a 3D `[x,y,z]` vector; off-by-one when slicing a longer array.","solutions":["Pass a two-element numeric tuple such as `center: [0.5, 0.5]`.","Omit `center` to use the default `[0.5, 0.5]`.","Convert point objects with `center: [point.x, point.y]` and ensure both are finite before passing."],"exampleFix":"// before\nrings({center: pointerPosition}); // {x: number, y: number}\n// after\nrings({center: [pointerPosition.x, pointerPosition.y]});","handlingStrategy":"validation","validationCode":"const validateRingsCenter = (center: unknown): [number, number] | undefined => {\n  if (center === undefined) return undefined;\n  if (!Array.isArray(center) || center.length !== 2 ||\n      center.some((c) => typeof c !== 'number' || !Number.isFinite(c))) {\n    throw new TypeError('center must be a [number, number] tuple');\n  }\n  const [x, y] = center as [number, number];\n  if (x < 0 || x > 1 || y < 0 || y > 1) {\n    throw new TypeError('center components must be within [0, 1]');\n  }\n  return [x, y];\n};\n\nrings({center: validateRingsCenter(maybeCenter)});","typeGuard":"const isRingsCenter = (v: unknown): v is [number, number] =>\n  Array.isArray(v) &&\n  v.length === 2 &&\n  v.every((c) => typeof c === 'number' && Number.isFinite(c));","tryCatchPattern":null,"preventionTips":["Always pass `center` as a tuple literal `[x, y]`, not a point object.","When reading from JSON, coerce strings with `Number()` and validate finiteness.","Constrain interactive drag handlers so the returned value is always a 2-tuple."],"tags":["validation","rings-effect","effects","params","tuple"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}