{"record":{"id":"9a44b3122be067ea","repo":"remotion-dev/remotion","slug":"name-must-be-greater-than-or-equal-to-0-but-9a44b3","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/lines.ts","lineNumber":174,"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":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/lines.ts#L156-L192","documentation":"Thrown by the Lines effect's validateNonNegative helper when a numeric parameter that must be >= 0 is given a negative value. In the shipped code this only guards the resolved gap (params.gap after applying the default of 0), so it fires when gap < 0. It is a TypeError raised during parameter validation before any WebGL work begins.","triggerScenarios":"Calling lines({ gap: -1 }) (or any negative number for gap) on the Lines effect. The check runs after defaults are applied, so an explicitly negative gap is the only trigger; thickness is guarded separately by validatePositive.","commonSituations":"Passing an animated/keyframed gap that undershoots below 0, or computing gap from an expression that can go negative. Confusing gap with thickness (which has the stricter > 0 rule).","solutions":["Set gap to 0 or a positive pixel value (0 means stripes pack solid).","Clamp any animated gap with Math.max(0, value) before passing it to lines().","Re-read the LinesParams JSDoc: gap is a transparent gap in pixels, default 0."],"exampleFix":"// before\nlines({ gap: animatedGap }) // animatedGap can be -5\n\n// after\nlines({ gap: Math.max(0, animatedGap) })","handlingStrategy":"validation","validationCode":"const safeGap = Math.max(0, Number.isFinite(gap) ? gap : 0);\nlines({ gap: safeGap });","typeGuard":"const isNonNegative = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0;","tryCatchPattern":null,"preventionTips":["Always clamp animated gap values to >= 0 before passing to lines().","Treat the LinesParams JSDoc as the source of truth: gap is a transparent pixel gap defaulting to 0.","Distinguish gap (>= 0) from thickness (> 0) — they use different validators."],"tags":["validation","lines-effect","typescript","params"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}