{"record":{"id":"300950e03c78f52d","repo":"remotion-dev/remotion","slug":"name-must-be-a-number-number-tuple-300950","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/fisheye/index.ts","lineNumber":110,"sourceCode":"\nconst resolve = (p: FisheyeParams): FisheyeResolved => ({\n\tfieldOfView: p.fieldOfView ?? DEFAULT_FISHEYE_FIELD_OF_VIEW,\n\tcenter: [...(p.center ?? DEFAULT_FISHEYE_CENTER)] as FisheyeUvCoordinate,\n\tradius: p.radius ?? DEFAULT_FISHEYE_RADIUS,\n\tzoom: p.zoom ?? DEFAULT_FISHEYE_ZOOM,\n});\n\nconst assertOptionalUvCoordinate = (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\nconst validatePositive = (value: number, name: string): void => {\n\tif (value <= 0) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than 0, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateFisheyeParams = (params: FisheyeParams): void => {\n\tassertEffectParamsObject(params, 'Fisheye');\n\tassertOptionalFiniteNumber(params.fieldOfView, 'fieldOfView');\n\tassertOptionalUvCoordinate(params.center, 'center');\n\tassertOptionalFiniteNumber(params.radius, 'radius');\n\tassertOptionalFiniteNumber(params.zoom, 'zoom');\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/fisheye/index.ts#L92-L128","documentation":"Thrown by assertOptionalUvCoordinate when the fisheye() effect receives a 'center' value that is defined but is not an array of exactly two finite numbers. The fisheye effect expects 'center' as a UV-space [x, y] coordinate (each 0..1) so the lens distortion can be offset within the frame. Any other shape (string, object, length-3 array, NaN/Infinity member, nested arrays) is rejected because the GLSL sampler would otherwise read garbage.","triggerScenarios":"Calling fisheye({center: 0.5}) with a scalar, fisheye({center: [0.5]}) or fisheye({center: [0.5, 0.5, 0.5]}) with the wrong arity, fisheye({center: ['0.5', '0.5']}) with strings, fisheye({center: [0.5, NaN]}), or passing an object like {x,y} instead of a tuple.","commonSituations":"Porting center coordinates from libraries that accept {x, y} objects (Framer Motion, GSAP) or [x, y, z] triples; deserializing center from JSON where numbers became strings; off-by-one copy of a vec3 from a 3D scene.","solutions":["Pass center as an explicit two-number tuple, e.g. fisheye({center: [0.5, 0.5]}).","If the value comes from JSON or user input, coerce and validate with Number() and isFinite before calling fisheye().","Leave center undefined to use the default [0.5, 0.5]."],"exampleFix":"// before\nfisheye({center: 0.5});\nfisheye({center: ['0.5', '0.5']});\n// after\nfisheye({center: [0.5, 0.5]});\nfisheye({center: [Number(raw.x), Number(raw.y)]});","handlingStrategy":"type-guard","validationCode":"const isUvTuple = (v: unknown): v is [number, number] =>\n  Array.isArray(v) &&\n  v.length === 2 &&\n  v.every((x) => typeof x === 'number' && Number.isFinite(x));\n\nif (center !== undefined && !isUvTuple(center)) {\n  throw new Error('center must be a [number, number] tuple');\n}","typeGuard":"const isUvTuple = (v: unknown): v is [number, number] =>\n  Array.isArray(v) &&\n  v.length === 2 &&\n  v.every((x) => typeof x === 'number' && Number.isFinite(x));","tryCatchPattern":null,"preventionTips":["Type the prop as [number, number] in your own component wrappers so TypeScript rejects scalars and wrong arities at compile time.","Validate deserialized config (JSON, URL params) with the type guard before forwarding to fisheye().","Keep center undefined unless you genuinely need to offset the lens."],"tags":["validation","fisheye","effects","tuple","type-error"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}