{"record":{"id":"6f7b4ae31ad0da91","repo":"remotion-dev/remotion","slug":"name-must-be-a-number-number-tuple-6f7b4a","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/skew.ts","lineNumber":86,"sourceCode":"};\n\nconst resolve = (params: SkewParams): SkewResolved => ({\n\tx: params.x ?? DEFAULT_X,\n\ty: params.y ?? DEFAULT_Y,\n\torigin: [...(params.origin ?? DEFAULT_ORIGIN)] as SkewOrigin,\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 validateUvCoordinate = (value: number, name: string): void => {\n\tif (value < 0 || value > 1) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be between 0 and 1, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateAngle = (value: number, name: string): void => {\n\tif (Math.abs(value) >= MAX_ABSOLUTE_ANGLE) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/skew.ts#L68-L104","documentation":"The skew() effect's assertOptionalUvCoordinate helper validates the optional 'origin' parameter. If provided, it must be an array of exactly two finite numbers — a [number, number] tuple in UV coordinate space. Passing anything else (wrong length, non-array, non-number elements, NaN/Infinity) throws this TypeError before the effect runs.","triggerScenarios":"Calling skew({ origin: [0.5] }) (wrong length), skew({ origin: 'center' }) (not an array), skew({ origin: [0.5, 0.5, 0.5] }) (three elements), skew({ origin: [0.5, NaN] }) (non-finite element), or skew({ origin: [0.5, '0.5'] }) (string element). The parameter is optional — omitting it entirely is valid and uses the default [0.5, 0.5].","commonSituations":"Passing a 3-element vector or object {x, y} instead of a 2-element array; deserializing origin from JSON that used a different format; spreading an array of unknown length; passing a React state variable that was initialized to null or an empty array.","solutions":["Ensure origin is a 2-element array of finite numbers: [x, y] where both are numbers (not strings, not NaN, not null).","Omit origin entirely to use the default [0.5, 0.5].","If the value comes from user input or deserialization, validate it before passing to skew().","Use a TypeScript type annotation (SkewOrigin = readonly [number, number]) to catch mismatches at compile time."],"exampleFix":"// before — wrong shape\nskew({ x: 20, y: 10, origin: { x: 0.5, y: 0.5 } })\n// before — wrong length\nskew({ x: 20, y: 10, origin: [0.5, 0.5, 0] })\n\n// after — correct [number, number] tuple\nskew({ x: 20, y: 10, origin: [0.5, 0.5] })","handlingStrategy":"type-guard","validationCode":"// Validate the origin tuple before calling skew\nfunction validateSkewOrigin(origin: unknown): [number, number] {\n  if (origin === undefined) return [0.5, 0.5]; // default\n  if (\n    Array.isArray(origin) &&\n    origin.length === 2 &&\n    origin.every((v) => typeof v === 'number' && Number.isFinite(v))\n  ) {\n    return [origin[0], origin[1]];\n  }\n  throw new Error('origin must be a [number, number] tuple of finite values');\n}\n\nconst origin = validateSkewOrigin(userInput);\nskew({ x: 20, y: 0, origin });","typeGuard":"const isNumberTuple = (v: unknown): v is readonly [number, number] =>\n  Array.isArray(v) &&\n  v.length === 2 &&\n  typeof v[0] === 'number' && Number.isFinite(v[0]) &&\n  typeof v[1] === 'number' && Number.isFinite(v[1]);\n\n// Usage:\nif (isNumberTuple(params.origin)) {\n  skew({ x: 20, origin: params.origin });\n} else {\n  // handle invalid shape\n}","tryCatchPattern":"try {\n  skew({ x: 20, y: 0, origin: rawOrigin });\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('[number, number] tuple')) {\n    // Fall back to default origin\n    skew({ x: 20, y: 0 });\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always pass origin as a 2-element array of finite numbers: [x, y].","Omit origin entirely to use the default [0.5, 0.5].","Use the SkewOrigin type (readonly [number, number]) to catch mismatches at compile time.","Validate deserialized or user-provided origin values before passing them to skew()."],"tags":["validation","typescript","skew","parameters","tuple"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}