remotion-dev/remotion · error · TypeError
"${name}" must be greater than or equal to 0, but got ${JSON
Error message
"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)} What it means
Thrown by the `rings()` effect when its `gap` prop resolves to a negative number. `gap` is the transparent pixel gap between consecutive colored rings and the shader treats it as an unsigned distance, so the effect rejects any value below 0. The check runs in `validateRingsParams` via the shared `validateNonNegative` helper, after `gap` is defaulted to `0` when omitted.
Source
Thrown at packages/effects/src/rings.ts:150
center: [...(p.center ?? DEFAULT_CENTER)] as RingsCenter,
thickness,
spacing: thickness + gap,
offset: p.offset ?? DEFAULT_OFFSET,
maskToSourceAlpha: p.maskToSourceAlpha ?? DEFAULT_MASK_TO_SOURCE_ALPHA,
};
};
const validatePositive = (value: number, name: string): void => {
if (value <= 0) {
throw new TypeError(
`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`,
);
}
};
const validateNonNegative = (value: number, name: string): void => {
if (value < 0) {
throw new TypeError(
`"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)}`,
);
}
};
const validateColors = (colors: unknown): void => {
if (colors === undefined) {
return;
}
if (!Array.isArray(colors) || colors.length < 2) {
throw new TypeError(
`"colors" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`,
);
}
for (let i = 0; i < colors.length; i++) {
assertRequiredColor(colors[i], `colors[${i}]`);View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Set `gap` to a non-negative number, or omit it to use the default of `0`.
- Clamp animated values with `Math.max(0, value)` or use `interpolate(..., {extrapolateLeft: 'clamp'})`.
- Validate external/serialized input before passing it to `rings()`.
Example fix
// before
rings({gap: interpolate(frame, [0, 30], [10, -10])});
// after
rings({
gap: interpolate(frame, [0, 30], [10, 0], {extrapolateRight: 'clamp'}),
}); Defensive patterns
Strategy: validation
Validate before calling
const validateRingsGap = (gap: unknown): number | undefined => {
if (gap === undefined) return undefined;
if (typeof gap !== 'number' || !Number.isFinite(gap) || gap < 0) {
throw new TypeError(`gap must be a finite non-negative number, got ${String(gap)}`);
}
return gap;
};
// before calling rings()
const safeGap = validateRingsGap(myGap);
rings({gap: safeGap}); Type guard
const isNonNegativeFinite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0;
Prevention
- Always clamp animated `gap` output ranges with `extrapolateLeft: 'clamp'`.
- Treat `gap` as an unsigned pixel distance in your own types.
- Run a single `validateRingsGap` helper on serialized/external input before composing.
When it happens
Trigger: Call `rings({gap: -5})`, or animate `gap` with an interpolate() whose output range dips below 0 (e.g. `interpolate(frame, [0, 30], [10, -10])`). Also triggered by feeding `gap` from an unvalidated external input such as a JSON config or a slider that allows negatives.
Common situations: Animating the gap closed and overshooting into negatives; passing through a computed value like `gap: spacing - margin` where the subtraction underflows; reusing a numeric field from another effect (e.g. an `offset` that may be signed) as `gap` without clamping.
Related errors
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be greater than or equal to 0, but got ${JSON
- "colors" must be an array with at least 2 colors, but got ${
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be ${formatEnum(variants)}, but got ${JSON.st
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/463186aedbcd7b7a.
Report an issue: GitHub.