{"record":{"id":"18e2f7d8db44a199","repo":"remotion-dev/remotion","slug":"name-must-be-greater-than-or-equal-to-0-but-18e2f7","errorCode":null,"errorMessage":"\"${name}\" must be greater than or equal to 0, but got ${JSON.stringify(value)}","messagePattern":"\"(.+?)\" must be greater than or equal to 0, but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/zigzag.ts","lineNumber":204,"sourceCode":"\t}\n\n\treturn `${variants\n\t\t.slice(0, -1)\n\t\t.map((variant) => `\"${variant}\"`)\n\t\t.join(', ')} or \"${variants[variants.length - 1]}\"`;\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 validateNonNegative = (value: number, name: string): void => {\n\tif (value < 0) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than or equal to 0, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateColors = (colors: unknown): void => {\n\tif (colors === undefined) {\n\t\treturn;\n\t}\n\n\tif (!Array.isArray(colors) || colors.length < 2) {\n\t\tthrow new TypeError(\n\t\t\t`\"colors\" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`,\n\t\t);\n\t}\n\n\tfor (let i = 0; i < colors.length; i++) {\n\t\tassertRequiredColor(colors[i], `colors[${i}]`);","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/zigzag.ts#L186-L222","documentation":"Zigzag validates that gap and amplitude are non-negative (>= 0) via validateNonNegative, throwing a TypeError naming the field. gap defaults to 0 and amplitude to 40; unlike thickness/wavelength, zero is permitted, but negative values are rejected because negative spacing/amplitude has no meaningful visual interpretation in the stripe layout.","triggerScenarios":"Calling zigzag({gap: -5}) or zigzag({amplitude: -20}); or an animated gap/amplitude value that crosses below zero.","commonSituations":"An interpolation overshooting below zero at keyframe endpoints; computing gap/amplitude from a delta that can go negative; assuming amplitude wraps or modulates like an angle.","solutions":["Pass gap >= 0 (0 is valid and means stripes touch).","Pass amplitude >= 0; use angle to control orientation, not negative amplitude.","Clamp animated values with Math.max(0, value) before passing them in."],"exampleFix":"// before\nzigzag({gap: -5});\nzigzag({amplitude: animVal}); // throws when animVal < 0\n\n// after\nzigzag({gap: Math.max(0, g)});\nzigzag({amplitude: Math.max(0, animVal)});","handlingStrategy":"validation","validationCode":"import {zigzag} from '@remotion/effects';\n\nconst gap = computedGap;       // may be negative\nconst amplitude = animAmp;     // may be negative\n\nconst safeGap = Math.max(0, gap);\nconst safeAmp = Math.max(0, amplitude);\n\nzigzag({gap: safeGap, amplitude: safeAmp});","typeGuard":"const isNonNegativeNumber = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0;\n\n// usage:\nif (!isNonNegativeNumber(params.gap)) params.gap = 0;","tryCatchPattern":"try {\n  return <VideoEffects effects={[zigzag({gap, amplitude})]} />;\n} catch (err) {\n  if (err instanceof TypeError && /must be greater than or equal to 0/.test(err.message)) {\n    return <VideoEffects effects={[zigzag({gap: Math.max(0, gap), amplitude: Math.max(0, amplitude)})]} />;\n  }\n  throw err;\n}","preventionTips":["gap and amplitude accept 0 but not negatives; clamp animated values with Math.max(0, x).","Use angle (not negative amplitude) to control orientation.","When feeding values from external data, validate or clamp before passing."],"tags":["validation","typescript","api-misuse","effect-params"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}