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 radialProgressivePixelate effect validates that optional UV-coordinate parameters (such as 'center') are [number, number] tuples. If a value is provided but is not a 2-element array of finite numbers, the effect throws a TypeError before any GPU work begins. This is a parameter-shape guard, not a runtime/GPU error.

Source

Thrown at packages/effects/src/radial-progressive-pixelate/index.ts:147

	width: params.width ?? DEFAULT_WIDTH,
	height: params.height ?? DEFAULT_HEIGHT,
	rotation: params.rotation ?? DEFAULT_ROTATION,
	start: params.start ?? DEFAULT_START,
	startBlockSize: params.startBlockSize ?? DEFAULT_START_BLOCK_SIZE,
	endBlockSize: params.endBlockSize ?? DEFAULT_END_BLOCK_SIZE,
});

const assertOptionalUvCoordinate = (value: unknown, name: string): void => {
	if (value === undefined) {
		return;
	}

	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 validateBlockSize = (value: number, name: string): void => {
	if (value < 1) {
		throw new TypeError(`"${name}" must be >= 1`);
	}
};

const validateParams = (params: RadialProgressivePixelateParams): void => {
	assertEffectParamsObject(params, 'Radial progressive pixelate');
	assertOptionalUvCoordinate(params.center, 'center');
	assertOptionalFiniteNumber(params.width, 'width');
	assertOptionalFiniteNumber(params.height, 'height');
	assertOptionalFiniteNumber(params.rotation, 'rotation');
	validateNonNegative(params.width ?? DEFAULT_WIDTH, 'width');
	validateNonNegative(params.height ?? DEFAULT_HEIGHT, 'height');
	assertOptionalFiniteNumber(params.start, 'start');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass center as a 2-element array of finite numbers: [x, y] in the 0–1 UV range
  2. If using an object internally, convert it: center: [obj.x, obj.y] before passing
  3. Run Number.isFinite on each component before constructing the tuple
  4. Omit the parameter entirely to use the default if you do not have a valid value

Example fix

// before
radialProgressivePixelate({ center: { x: 0.5, y: 0.5 } })
// after
radialProgressivePixelate({ center: [0.5, 0.5] })
Defensive patterns

Strategy: type-guard

Validate before calling

const center = [0.5, 0.5];
if (!Array.isArray(center) || center.length !== 2 || !center.every(v => typeof v === 'number' && Number.isFinite(v))) {
  throw new Error('center must be [number, number]');
}
radialProgressivePixelate({ center: center as [number, number] });

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: Passing radialProgressivePixelate({ center: [0.5] }) (wrong length), center: 'middle' (wrong type), center: [0.5, NaN] (non-finite), or center: {x: 0.5, y: 0.5} (object instead of array).

Common situations: Passing an object {x, y} instead of an array [x, y]; passing a 3-element array from code that shares a coordinate type with a 3D system; accidentally passing NaN from a division-by-zero calculation upstream.

Related errors


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