remotion-dev/remotion · error · TypeError

"topLeft" must be above and to the left of "bottomRight"

Error message

"topLeft" must be above and to the left of "bottomRight"

What it means

After resolving defaults and confirming both coordinates are valid tuples, the regionBlur effect checks that topLeft is strictly above and to the left of bottomRight (both x and y components strictly less). If topLeft[0] >= bottomRight[0] or topLeft[1] >= bottomRight[1], the region has zero or negative area and the effect throws a TypeError.

Source

Thrown at packages/effects/src/region-blur/index.ts:126

const validateRegionBlurParams = (params: RegionBlurParams): void => {
	assertEffectParamsObject(params, 'Region blur');
	assertRequiredUvCoordinate(params.topLeft, 'topLeft');
	assertRequiredUvCoordinate(params.bottomRight, 'bottomRight');
	assertOptionalFiniteNumber(params.blurRadius, 'blurRadius');
	assertOptionalFiniteNumber(params.feather, 'feather');
	assertOptionalFiniteNumber(params.roundness, 'roundness');

	const resolved = resolve(params);
	validateNonNegative(resolved.blurRadius, 'blurRadius');
	validateNonNegative(resolved.feather, 'feather');
	validateUnitInterval(resolved.roundness, 'roundness');

	if (
		resolved.topLeft[0] >= resolved.bottomRight[0] ||
		resolved.topLeft[1] >= resolved.bottomRight[1]
	) {
		throw new TypeError(
			'"topLeft" must be above and to the left of "bottomRight"',
		);
	}
};

export const regionBlur = createEffect<RegionBlurParams, RegionBlurState>({
	type: 'remotion/region-blur',
	label: 'regionBlur()',
	documentationLink: 'https://www.remotion.dev/docs/effects/region-blur',
	backend: 'webgl2',
	calculateKey: (params) => {
		const resolved = resolve(params);
		return `region-blur-${resolved.topLeft.join(':')}-${resolved.bottomRight.join(':')}-${resolved.blurRadius}-${resolved.feather}-${resolved.roundness}`;
	},
	setup: (target) => setupRegionBlur(target),
	apply: ({source, width, height, params, state, flipSourceY}) => {
		const resolved = resolve(params);
		applyRegionBlur({

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure topLeft x < bottomRight x and topLeft y < bottomRight y (note: y increases downward in UV space)
  2. Normalize coordinates before passing: sort the two points so topLeft has the smaller values
  3. In animated sequences, clamp the region to a minimum size (e.g. ensure at least 1px difference)
  4. If the region can legitimately be empty, conditionally omit the effect rather than passing a degenerate rectangle

Example fix

// before
regionBlur({ topLeft: [0.8, 0.2], bottomRight: [0.2, 0.8] })
// after
const x1 = 0.2, y1 = 0.2, x2 = 0.8, y2 = 0.8;
regionBlur({
  topLeft: [Math.min(x1, x2), Math.min(y1, y2)],
  bottomRight: [Math.max(x1, x2), Math.max(y1, y2)],
})
Defensive patterns

Strategy: validation

Validate before calling

const x1 = 0.2, y1 = 0.2, x2 = 0.8, y2 = 0.8;
const topLeft: [number, number] = [Math.min(x1, x2), Math.min(y1, y2)];
const bottomRight: [number, number] = [Math.max(x1, x2), Math.max(y1, y2)];
if (topLeft[0] >= bottomRight[0] || topLeft[1] >= bottomRight[1]) {
  throw new Error('Degenerate region');
}
regionBlur({ topLeft, bottomRight });

Prevention

When it happens

Trigger: Passing regionBlur({ topLeft: [0.8, 0.2], bottomRight: [0.2, 0.8] }) (x-axis inverted), regionBlur({ topLeft: [0.5, 0.5], bottomRight: [0.5, 0.8] }) (x-axis identical), or any case where the coordinates form a degenerate rectangle.

Common situations: Coordinates computed from dynamic layout where the region can collapse to a line; swapped topLeft/bottomRight during refactoring; passing identical points; animations that tween both corners to the same position.

Related errors


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