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 noiseDisplacement() effect requires a `center` prop that is a [number, number] tuple representing UV coordinates. assertRequiredUvCoordinate throws this TypeError when `center` is not a two-element array where both elements are finite numbers. This is a required parameter with no default.

Source

Thrown at packages/effects/src/noise-displacement.ts:188

	center: [...p.center] as NoiseDisplacementCenter,
	radius: p.radius,
	strength: p.strength ?? DEFAULT_STRENGTH,
	seed: p.seed ?? DEFAULT_SEED,
	grainSize: p.grainSize ?? DEFAULT_GRAIN_SIZE,
	passes: p.passes ?? DEFAULT_PASSES,
	blur: p.blur ?? DEFAULT_BLUR,
	feather: p.feather ?? DEFAULT_FEATHER,
	biasDirection: p.biasDirection ?? DEFAULT_BIAS_DIRECTION,
	biasAmount: p.biasAmount ?? DEFAULT_BIAS_AMOUNT,
});

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 assertOptionalIntegerNumber = (value: unknown, name: string): void => {
	if (value === undefined) {
		return;
	}

	if (!Number.isInteger(value)) {
		throw new TypeError(
			`"${name}" must be an integer, but got ${JSON.stringify(value)}`,
		);
	}
};

const validatePositive = (value: number, name: string): void => {
	if (value <= 0) {
		throw new TypeError(

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Provide center as a two-element numeric array: noiseDisplacement({ center: [0.5, 0.5], radius: 0.5 }).
  2. If using an object, convert it: center: [obj.x, obj.y].
  3. Ensure both components are finite numbers — check with Number.isFinite.
  4. Remember center is required (no default) unlike most other noiseDisplacement props.

Example fix

// before
noiseDisplacement({ center: {x: 0.5, y: 0.5}, radius: 0.5 })
noiseDisplacement({ center: [0.5], radius: 0.5 })

// after
noiseDisplacement({ center: [0.5, 0.5], radius: 0.5 })
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate center before calling noiseDisplacement()
const isValidCenter = (c: unknown): c is [number, number] =>
  Array.isArray(c) &&
  c.length === 2 &&
  c.every((item) => typeof item === 'number' && Number.isFinite(item));

if (!isValidCenter(params.center)) {
  throw new Error('center must be a [number, number] tuple');
}
const result = noiseDisplacement(params);

Type guard

const isNoiseDisplacementCenter = (
  v: unknown,
): v is readonly [number, number] =>
  Array.isArray(v) &&
  v.length === 2 &&
  typeof v[0] === 'number' &&
  typeof v[1] === 'number' &&
  Number.isFinite(v[0]) &&
  Number.isFinite(v[1]);

Prevention

When it happens

Trigger: Calling noiseDisplacement({ center: [0.5] }) (wrong length), noiseDisplacement({ center: [0.5, '0.5'] }) (string element), noiseDisplacement({ center: {x: 0.5, y: 0.5} }) (object not array), noiseDisplacement({ center: [NaN, 0.5] }), or omitting center entirely.

Common situations: Passing an object {x, y} instead of a tuple; deserializing center from JSON where it becomes a different shape; using a 3-element array by mistake; passing Infinity or NaN from upstream math; omitting the required center prop.

Related errors


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