remotion-dev/remotion · error · TypeError
"stops" must be >= ${MIN_STOPS}, but got ${JSON.stringify(st
Error message
"stops" must be >= ${MIN_STOPS}, but got ${JSON.stringify(stops)} What it means
Thrown by validateExposureParams() in exposure.ts when the resolved `stops` value is below MIN_STOPS (-5). It is a TypeError fired during the effect's validateParams step, before any WebGL work, so the user gets fast, deterministic feedback. The offending value is JSON-stringified into the message.
Source
Thrown at packages/effects/src/exposure.ts:56
readonly vbo: WebGLBuffer;
readonly textureSource: WebGLTexture;
readonly uniforms: {
readonly uSource: WebGLUniformLocation | null;
readonly uStops: WebGLUniformLocation | null;
};
};
const resolve = (params: ExposureParams): ExposureResolved => ({
stops: params.stops ?? DEFAULT_STOPS,
});
const validateExposureParams = (params: ExposureParams): void => {
assertEffectParamsObject(params, 'Exposure');
assertOptionalFiniteNumber(params.stops, 'stops');
const {stops} = resolve(params);
if (stops < MIN_STOPS) {
throw new TypeError(
`"stops" must be >= ${MIN_STOPS}, but got ${JSON.stringify(stops)}`,
);
}
if (stops > MAX_STOPS) {
throw new TypeError(
`"stops" must be <= ${MAX_STOPS}, but got ${JSON.stringify(stops)}`,
);
}
};
const VERTEX_SHADER = /* glsl */ `#version 300 es
in vec2 aPos;
in vec2 aUv;
out vec2 vUv;
void main() {
vUv = aUv;View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Clamp the animated value to [-5, 5] before passing it: exposure({ stops: Math.max(-5, Math.min(5, value)) }).
- Inspect the easing/interpolation for overshoot and pick an easing that stays in range (e.g. linear or ease-in-out without spring overshoot).
- Validate the source data feeding stops and reject or clamp values outside [-5, 5] upstream.
- If you genuinely need more than ±5 stops, layer two exposure() effects or request a wider range from the effect maintainer.
Example fix
// before
exposure({ stops: springValue }); // spring overshoots to -5.4 -> throws
// after
exposure({ stops: Math.max(-5, Math.min(5, springValue)) }); Defensive patterns
Strategy: validation
Validate before calling
// Clamp before passing to exposure(); range is [-5, 5] (MIN_STOPS..MAX_STOPS).
const EXPOSURE_STOPS_MIN = -5;
const EXPOSURE_STOPS_MAX = 5;
const clampStops = (stops: number): number =>
Math.max(EXPOSURE_STOPS_MIN, Math.min(EXPOSURE_STOPS_MAX, stops));
// usage: exposure({ stops: clampStops(animatedValue) }) Type guard
const isExposureStops = (v: unknown): v is number =>
typeof v === 'number' &&
Number.isFinite(v) &&
v >= -5 &&
v <= 5;
// guard: if (isExposureStops(value)) exposure({ stops: value }); else /* clamp or skip */ Prevention
- Clamp animated stops to [-5, 5] at the source (e.g. interpolate with extrapolateLeft/Right: 'clamp').
- Avoid spring/bounce easing on stops; they overshoot past the bounds.
- Constrain upstream data (config, schema, UI slider) so stops can never be below -5.
- Run a unit test asserting your stops stream stays within [-5, 5].
When it happens
Trigger: Calling exposure({ stops: x }) with x < -5 (e.g. exposure({ stops: -6 }), or a NaN that slipped past assertOptionalFiniteNumber only if the finite-number guard was bypassed). Resolution applies the DEFAULT_STOPS (0) only when stops is undefined; any provided number below -5 trips this branch.
Common situations: Animations interpolating stops with a curve that overshoots past -5 (e.g. an easing that briefly hits -5.5); reading stops from a data file or control that allows out-of-range values; passing a negativeInfinity by mistake; UI slider with a wider range than the schema enforces.
Related errors
- "stops" must be <= ${MAX_STOPS}, but got ${JSON.stringify(st
- "exposure" must be >= ${MIN_EXPOSURE}, but got ${JSON.string
- "exposure" must be <= ${MAX_EXPOSURE}, but got ${JSON.string
- "${name}" must be >= 1
- "${name}" must be greater than 0, but got ${JSON.stringify(v
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/085dd707f94d7ca5.
Report an issue: GitHub.