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

  1. Clamp exposure to [-5, 5] before passing it: Math.max(-5, Math.min(5, value)).
  2. If using interpolate(), set its range/extrapolateLeft/Right to 'clamp' so animation never undershoots.
  3. Re-check the value printed in the error message and adjust the source of the number.
  4. 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

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


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/46e91f87be03003a. Report an issue: GitHub.