remotion-dev/remotion · error · TypeError

"${name}" must be a [number, number] tuple

Error message

"${name}" must be a [number, number] tuple

What it means

The regionBlur effect requires both topLeft and bottomRight UV coordinates as [number, number] tuples. Unlike the optional variant in radial-progressive-pixelate, these are mandatory—if either is missing, not a 2-element array, or contains non-finite numbers, the effect throws a TypeError immediately.

Source

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

		hiddenFromList: false,
	},
} as const satisfies InteractivitySchema;

const resolve = (params: RegionBlurParams): RegionBlurResolved => ({
	topLeft: [...params.topLeft] as RegionBlurUvCoordinate,
	bottomRight: [...params.bottomRight] as RegionBlurUvCoordinate,
	blurRadius: params.blurRadius ?? DEFAULT_BLUR_RADIUS,
	feather: params.feather ?? DEFAULT_FEATHER,
	roundness: params.roundness ?? DEFAULT_ROUNDNESS,
});

const assertRequiredUvCoordinate = (value: unknown, name: string): void => {
	if (
		!Array.isArray(value) ||
		value.length !== 2 ||
		value.some((item) => typeof item !== 'number' || !Number.isFinite(item))
	) {
		throw new TypeError(`"${name}" must be a [number, number] tuple`);
	}
};

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] ||

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Provide both topLeft and bottomRight as [number, number] arrays in the 0–1 UV range
  2. Convert from pixel coordinates: [pixelX / width, pixelY / height]
  3. If using an object, destructure into the array form: topLeft: [pt.x, pt.y]
  4. Add a TypeScript type annotation to catch shape mismatches at compile time

Example fix

// before
regionBlur({ topLeft: { x: 0.2, y: 0.2 }, bottomRight: [0.8, 0.8] })
// after
regionBlur({ topLeft: [0.2, 0.2], bottomRight: [0.8, 0.8] })
Defensive patterns

Strategy: type-guard

Validate before calling

const isUvTuple = (v: unknown): v is [number, number] =>
  Array.isArray(v) &&
  v.length === 2 &&
  v.every((item) => typeof item === 'number' && Number.isFinite(item));

if (!isUvTuple(topLeft) || !isUvTuple(bottomRight)) {
  throw new Error('topLeft and bottomRight must be [number, number]');
}
regionBlur({ topLeft, bottomRight });

Type guard

const isUvTuple = (v: unknown): v is [number, number] =>
  Array.isArray(v) &&
  v.length === 2 &&
  v.every((item) => typeof item === 'number' && Number.isFinite(item));

Prevention

When it happens

Trigger: Calling regionBlur({ topLeft: [0.2, 0.2] }) (missing bottomRight), regionBlur({ topLeft: 'top', bottomRight: [0.8, 0.8] }) (string instead of array), or regionBlur({ topLeft: [0.2], bottomRight: [0.8, 0.8] }) (wrong length).

Common situations: Forgetting one of the two required coordinates; passing CSS-style coordinate objects; sharing a partial coordinate from destructured state; typo in the parameter name.

Related errors


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