remotion-dev/remotion · error · TypeError
"exposure" must be >= ${MIN_EXPOSURE}, but got ${JSON.string
Error message
"exposure" must be >= ${MIN_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)} What it means
Thrown by validateColorCorrectionParams when the resolved exposure value is below MIN_EXPOSURE (-5). Exposure is measured in stops and is clamped by the schema to [-5, 5]; a value below -5 is rejected with a TypeError that echoes the offending value. This is a caller-input error, not an environment failure.
Source
Thrown at packages/effects/src/color-correction.ts:169
});
const validateColorCorrectionParams = (params: ColorCorrectionParams): void => {
assertEffectParamsObject(params, 'Color correction');
assertOptionalFiniteNumber(params.exposure, 'exposure');
assertOptionalFiniteNumber(params.contrast, 'contrast');
assertOptionalFiniteNumber(params.pivot, 'pivot');
assertOptionalFiniteNumber(params.shadows, 'shadows');
assertOptionalFiniteNumber(params.highlights, 'highlights');
assertOptionalFiniteNumber(params.whites, 'whites');
assertOptionalFiniteNumber(params.blacks, 'blacks');
assertOptionalFiniteNumber(params.temperature, 'temperature');
assertOptionalFiniteNumber(params.tint, 'tint');
assertOptionalFiniteNumber(params.saturation, 'saturation');
assertOptionalFiniteNumber(params.vibrance, 'vibrance');
const resolved = resolve(params);
if (resolved.exposure < MIN_EXPOSURE) {
throw new TypeError(
`"exposure" must be >= ${MIN_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)}`,
);
}
if (resolved.exposure > MAX_EXPOSURE) {
throw new TypeError(
`"exposure" must be <= ${MAX_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)}`,
);
}
validateNonNegative(resolved.contrast, 'contrast');
validateUnitInterval(resolved.pivot, 'pivot');
validateSignedUnitInterval(resolved.shadows, 'shadows');
validateSignedUnitInterval(resolved.highlights, 'highlights');
validateSignedUnitInterval(resolved.whites, 'whites');
validateSignedUnitInterval(resolved.blacks, 'blacks');
validateSignedUnitInterval(resolved.temperature, 'temperature');
validateSignedUnitInterval(resolved.tint, 'tint');View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Clamp exposure to [-5, 5] before passing it: Math.max(-5, Math.min(5, value)).
- If using interpolate(), set its range/extrapolateLeft/Right to 'clamp' so animation never undershoots.
- Re-check the value printed in the error message and adjust the source of the number.
- Leave exposure unset to accept the default of 0 if no adjustment is needed.
Example fix
// before
import {colorCorrection} from '@remotion/effects';
colorCorrection({exposure: -7}); // throws: must be >= -5
// after
const exposure = Math.max(-5, Math.min(5, animatedValue));
colorCorrection({exposure}); Defensive patterns
Strategy: validation
Validate before calling
const EXPOSURE_MIN = -5;
const EXPOSURE_MAX = 5;
function assertExposure(value: number | undefined): number | undefined {
if (value === undefined) return value;
if (!Number.isFinite(value)) {
throw new TypeError(`exposure must be finite, got ${value}`);
}
if (value < EXPOSURE_MIN || value > EXPOSURE_MAX) {
throw new TypeError(
`exposure must be in [${EXPOSURE_MIN}, ${EXPOSURE_MAX}], got ${value}`,
);
}
return value;
}
// call before colorCorrection({exposure: assertExposure(myValue)}) Type guard
const isExposure = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= -5 && v <= 5;
Prevention
- Clamp animated exposure with Math.max(-5, Math.min(5, value)) at the call site.
- Use interpolate(..., {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}) for any driver of exposure.
- Unit-test parameter producers (springs, sliders) against the [-5, 5] range.
- Remember exposure is in stops, not a 0-1 or 0-100 scale.
When it happens
Trigger: Calling colorCorrection({exposure: x}) (or an interactivity-schema-driven value) where x < -5, including x being a non-default negative number resolved from params. Validation runs in validateColorCorrectionParams at color-correction.ts:168 before any GL work, right after assertOptionalFiniteNumber confirms exposure is a finite number.
Common situations: Passing a computed/interpolated exposure (e.g. from a Spring or interpolate) whose range was not clamped, copying a value from another tool's scale, or driving exposure from a slider whose min was set below -5.
Related errors
- "exposure" must be <= ${MAX_EXPOSURE}, but got ${JSON.string
- "${name}" must be >= 0, but got ${JSON.stringify(value)}
- "${name}" must be <= 1, but got ${JSON.stringify(value)}
- "stops" must be >= ${MIN_STOPS}, but got ${JSON.stringify(st
- "stops" must be <= ${MAX_STOPS}, but got ${JSON.stringify(st
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/46e91f87be03003a.
Report an issue: GitHub.