remotion-dev/remotion · error
"progress" must be >= 0
Error message
"progress" must be >= 0
What it means
The <Tear> effect validates its parameters before rendering. `progress` controls how far the tear has ripped (0 = intact; values above 1 push the pieces farther apart). After substituting defaults, the effect throws if the resolved progress is negative, since a negative progress is meaningless. Note the check runs on the RESOLVED value, so passing undefined is fine (defaults to 0.5) but explicitly passing a negative number fails.
Source
Thrown at packages/effects/src/tear.ts:75
readonly jaggedness?: number;
};
const resolve = (p: TearParams) => ({
progress: p.progress ?? DEFAULT_PROGRESS,
angle: p.angle ?? DEFAULT_ANGLE,
rotation: p.rotation ?? DEFAULT_ROTATION,
jaggedness: p.jaggedness ?? DEFAULT_JAGGEDNESS,
});
const validateTearParams = (params: TearParams): void => {
assertEffectParamsObject(params, 'Tear');
assertOptionalFiniteNumber(params.progress, 'progress');
assertOptionalFiniteNumber(params.angle, 'angle');
assertOptionalFiniteNumber(params.rotation, 'rotation');
assertOptionalFiniteNumber(params.jaggedness, 'jaggedness');
const r = resolve(params);
if (r.progress < 0) {
throw new Error('"progress" must be >= 0');
}
if (r.rotation < 0 || r.rotation > 90) {
throw new Error('"rotation" must be between 0 and 90');
}
if (r.jaggedness < 0) {
throw new Error('"jaggedness" must be >= 0');
}
};
type TearState = {
readonly gl: WebGL2RenderingContext;
readonly program: WebGLProgram;
readonly vao: WebGLVertexArrayObject;
readonly vbo: WebGLBuffer;
readonly texture: WebGLTexture;
readonly uSource: WebGLUniformLocation | null;View on GitHub (pinned to b2f4e34732)
Solutions
- Clamp progress to >= 0 before passing it: Math.max(0, value).
- If using interpolate(), set extrapolateLeft: 'clamp' so early frames do not produce negative values.
- Check the frame math driving the animation — ensure the range start is not before the animation begins.
- Verify the literal value: a negative sign may be a typo (progress={-1} vs progress={1}).
Example fix
// before
<Tear progress={frame / durationInFrames} />
// after
<Tear
progress={Math.max(0, frame / durationInFrames)}
/> Defensive patterns
Strategy: validation
Validate before calling
if (progress !== undefined && (!Number.isFinite(progress) || progress < 0)) {
throw new RangeError(`progress must be >= 0, got ${progress}`);
} Try / catch
try {
return <Tear progress={p} ... />;
} catch (e) {
if (e instanceof Error && e.message.includes('"progress" must be >= 0')) {
return <Tear progress={Math.max(0, p)} ... />;
}
throw e;
} Prevention
- Always clamp animated progress: Math.max(0, value).
- Use interpolate() with extrapolateLeft: 'clamp' for frame-derived progress.
- Check spring() overshoot — clamp its output if feeding progress.
- Guard against frame-before-start computations ((frame - startFrame) can be negative).
When it happens
Trigger: Calling <Tear progress={-0.1}> (or any negative number), or animating progress from a value that dips below 0, e.g. spring()/interpolate() output that undershoots (overshoot clamping disabled), or passing a NaN-adjacent calculation result that resolves negative after the finite-number assertion.
Common situations: Driving progress from a spring with damping that swings negative at the start; computing progress as (frame - startFrame)/duration where the frame is before startFrame; typo in a constant like progress={-1} intending 1.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "rotation" must be between 0 and 90
- "jaggedness" must be >= 0
- bezier x values must be in [0, 1] range
- Threshold is NaN
- Threshold is not finite
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/df9f476d13740a9b.
Report an issue: GitHub.