{"record":{"id":"46e91f87be03003a","repo":"remotion-dev/remotion","slug":"exposure-must-be-min-exposure-but-got-j","errorCode":null,"errorMessage":"\"exposure\" must be >= ${MIN_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)}","messagePattern":"\"exposure\" must be >= (.+?), but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/color-correction.ts","lineNumber":169,"sourceCode":"});\n\nconst validateColorCorrectionParams = (params: ColorCorrectionParams): void => {\n\tassertEffectParamsObject(params, 'Color correction');\n\tassertOptionalFiniteNumber(params.exposure, 'exposure');\n\tassertOptionalFiniteNumber(params.contrast, 'contrast');\n\tassertOptionalFiniteNumber(params.pivot, 'pivot');\n\tassertOptionalFiniteNumber(params.shadows, 'shadows');\n\tassertOptionalFiniteNumber(params.highlights, 'highlights');\n\tassertOptionalFiniteNumber(params.whites, 'whites');\n\tassertOptionalFiniteNumber(params.blacks, 'blacks');\n\tassertOptionalFiniteNumber(params.temperature, 'temperature');\n\tassertOptionalFiniteNumber(params.tint, 'tint');\n\tassertOptionalFiniteNumber(params.saturation, 'saturation');\n\tassertOptionalFiniteNumber(params.vibrance, 'vibrance');\n\n\tconst resolved = resolve(params);\n\tif (resolved.exposure < MIN_EXPOSURE) {\n\t\tthrow new TypeError(\n\t\t\t`\"exposure\" must be >= ${MIN_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)}`,\n\t\t);\n\t}\n\n\tif (resolved.exposure > MAX_EXPOSURE) {\n\t\tthrow new TypeError(\n\t\t\t`\"exposure\" must be <= ${MAX_EXPOSURE}, but got ${JSON.stringify(resolved.exposure)}`,\n\t\t);\n\t}\n\n\tvalidateNonNegative(resolved.contrast, 'contrast');\n\tvalidateUnitInterval(resolved.pivot, 'pivot');\n\tvalidateSignedUnitInterval(resolved.shadows, 'shadows');\n\tvalidateSignedUnitInterval(resolved.highlights, 'highlights');\n\tvalidateSignedUnitInterval(resolved.whites, 'whites');\n\tvalidateSignedUnitInterval(resolved.blacks, 'blacks');\n\tvalidateSignedUnitInterval(resolved.temperature, 'temperature');\n\tvalidateSignedUnitInterval(resolved.tint, 'tint');","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/color-correction.ts#L151-L187","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nimport {colorCorrection} from '@remotion/effects';\n\ncolorCorrection({exposure: -7}); // throws: must be >= -5\n\n// after\nconst exposure = Math.max(-5, Math.min(5, animatedValue));\ncolorCorrection({exposure});","handlingStrategy":"validation","validationCode":"const EXPOSURE_MIN = -5;\nconst EXPOSURE_MAX = 5;\n\nfunction assertExposure(value: number | undefined): number | undefined {\n  if (value === undefined) return value;\n  if (!Number.isFinite(value)) {\n    throw new TypeError(`exposure must be finite, got ${value}`);\n  }\n  if (value < EXPOSURE_MIN || value > EXPOSURE_MAX) {\n    throw new TypeError(\n      `exposure must be in [${EXPOSURE_MIN}, ${EXPOSURE_MAX}], got ${value}`,\n    );\n  }\n  return value;\n}\n\n// call before colorCorrection({exposure: assertExposure(myValue)})","typeGuard":"const isExposure = (v: unknown): v is number =>\n  typeof v === 'number' &&\n  Number.isFinite(v) &&\n  v >= -5 &&\n  v <= 5;","tryCatchPattern":null,"preventionTips":["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."],"tags":["color-correction","validation","typescript","params","exposure"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}