{"record":{"id":"5cc83d0fd5bafa4e","repo":"remotion-dev/remotion","slug":"hueshift-must-be-between-0-and-360-but-got-hu","errorCode":null,"errorMessage":"\"hueShift\" must be between 0 and 360, but got ${hueShift}","messagePattern":"\"hueShift\" must be between 0 and 360, but got (.+?)","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/light-leaks/src/LightLeak.tsx","lineNumber":288,"sourceCode":"\tcontrols,\n\t...sequenceProps\n}) => {\n\tconst {durationInFrames: videoDuration} = useVideoConfig();\n\tconst resolvedDuration = durationInFrames ?? videoDuration;\n\tif (typeof seed !== 'number' || !Number.isFinite(seed)) {\n\t\tthrow new TypeError(\n\t\t\t`\"seed\" must be a finite number, but got ${JSON.stringify(seed)}`,\n\t\t);\n\t}\n\n\tif (typeof hueShift !== 'number' || !Number.isFinite(hueShift)) {\n\t\tthrow new TypeError(\n\t\t\t`\"hueShift\" must be a finite number, but got ${JSON.stringify(hueShift)}`,\n\t\t);\n\t}\n\n\tif (hueShift < 0 || hueShift > 360) {\n\t\tthrow new RangeError(\n\t\t\t`\"hueShift\" must be between 0 and 360, but got ${hueShift}`,\n\t\t);\n\t}\n\n\treturn (\n\t\t<Sequence\n\t\t\tdurationInFrames={resolvedDuration}\n\t\t\tname=\"<LightLeak>\"\n\t\t\t_remotionInternalDocumentationLink=\"https://www.remotion.dev/docs/light-leaks/light-leak\"\n\t\t\tcontrols={controls}\n\t\t\t{...sequenceProps}\n\t\t\tstyle={style}\n\t\t>\n\t\t\t<LightLeakCanvas seed={seed} hueShift={hueShift} />\n\t\t</Sequence>\n\t);\n};\n","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/light-leaks/src/LightLeak.tsx#L270-L306","documentation":"LightLeak throws a RangeError when hueShift is a finite number but outside the inclusive range [0,360]. Hue is an angle in degrees, so values outside this band are not meaningful for the rotation applied to the texture.","triggerScenarios":"Passing hueShift = -10, 400, or any value outside 0..360; animating hueShift without clamping extrapolation.","commonSituations":"Using interpolate() without extrapolateLeft/Right:'clamp'; passing a raw 0..1 normalized float instead of degrees; building hueShift from user input that is unbounded.","solutions":["Wrap the value with modulo: `((hue % 360) + 360) % 360`.","Use interpolate(..., {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}).","Validate the range before passing to LightLeak."],"exampleFix":"// before\nconst hue = interpolate(frame, [0, 100], [0, 720]);\n<LightLeak hueShift={hue} />\n// after\nconst hue = interpolate(frame, [0, 100], [0, 360], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});\n<LightLeak hueShift={hue} />","handlingStrategy":"validation","validationCode":"function clampHue(h: number): number {\n  return ((Number(h) % 360) + 360) % 360;\n}","typeGuard":"const isHueInRange = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0 && v <= 360;","tryCatchPattern":null,"preventionTips":["Wrap hueShift with modulo before passing: ((h % 360) + 360) % 360.","Use interpolate(..., {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}).","Validate range in a wrapper component to centralize the clamp.","Treat hue as degrees, not a 0..1 normalized float."],"tags":["typescript","light-leaks","validation","range","react"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}