{"record":{"id":"e7c905b5b1311a30","repo":"remotion-dev/remotion","slug":"name-must-be-a-number-number-tuple-e7c905","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/halftone-linear-gradient.ts","lineNumber":220,"sourceCode":"const 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 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 validateHalftoneLinearGradientParams = (\n\tparams: HalftoneLinearGradientParams,\n): void => {\n\tassertEffectParamsObject(params, 'Halftone linear gradient');\n\tassertOptionalFiniteNumber(params.firstStopDotSize, 'firstStopDotSize');\n\tassertOptionalFiniteNumber(params.secondStopDotSize, 'secondStopDotSize');\n\tassertOptionalUvCoordinate(params.firstStopPosition, 'firstStopPosition');\n\tassertOptionalUvCoordinate(params.secondStopPosition, 'secondStopPosition');\n\tassertOptionalFiniteNumber(params.gridSize, 'gridSize');\n\tassertOptionalBoolean(params.maskToSourceAlpha, 'maskToSourceAlpha');\n\tassertOptionalEnum(\n\t\tparams.colorMode,\n\t\t'colorMode',\n\t\tHALFTONE_LINEAR_GRADIENT_COLOR_MODES,\n\t);","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/halftone-linear-gradient.ts#L202-L238","documentation":"TypeError thrown by halftone-linear-gradient's assertOptionalUvCoordinate (halftone-linear-gradient.ts:210) when firstStopPosition or secondStopPosition is provided but is not an array of exactly two finite numbers. UV coordinates position the gradient stops in [0..1] texture space.","triggerScenarios":"validateHalftoneLinearGradientParams calls assertOptionalUvCoordinate for firstStopPosition (line 230) and secondStopPosition (line 231). Triggered by: a non-array (object/string/number); an array of length other than 2; an array containing a non-number, NaN, or Infinity.","commonSituations":"Passing [0.5] or [0.1, 0.2, 0.3]; passing {x:0.5, y:0.5} instead of a tuple; a NaN leaking from a division; a string like '0.5,0.5'.","solutions":["Provide a two-element numeric tuple, e.g. [0.5, 0.5].","If converting from an object, map {x,y} -> [x, y] first.","Filter out NaN/Infinity before passing: tuple.map(Number.isFinite).","For optional usage, omit the prop entirely rather than passing null/undefined inside the array."],"exampleFix":"// before\n<halftoneLinearGradient firstStopPosition={{x: 0, y: 0}} />\n// -> \"firstStopPosition\" must be a [number, number] tuple\n\n// after\n<halftoneLinearGradient firstStopPosition={[0, 0]} />","handlingStrategy":"type-guard","validationCode":"const toUv = (v: unknown): [number, number] => {\n  if (Array.isArray(v) && v.length === 2 && v.every(n => typeof n === 'number' && Number.isFinite(n))) {\n    return [v[0], v[1]];\n  }\n  return [0, 0]; // or throw\n};","typeGuard":"const isUvCoordinate = (v: unknown): v is [number, number] =>\n  Array.isArray(v) &&\n  v.length === 2 &&\n  v.every((item) => typeof item === 'number' && Number.isFinite(item));","tryCatchPattern":"null","preventionTips":["Pass UV stops as plain tuples, not objects.","Map {x,y} -> [x, y] before passing.","Filter NaN/Infinity out of computed tuples.","To leave a stop default, omit the prop entirely."],"tags":["halftone-linear-gradient-effect","validation","typescript","tuple","params"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}