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
- Provide center as a two-element numeric array: noiseDisplacement({ center: [0.5, 0.5], radius: 0.5 }).
- If using an object, convert it: center: [obj.x, obj.y].
- Ensure both components are finite numbers — check with Number.isFinite.
- 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
- Use the NoiseDisplacementParams TypeScript type — center is required and typed as readonly [number, number].
- When converting from {x, y} objects, always produce a tuple: [obj.x, obj.y].
- Never omit the required center prop — it has no default unlike most other props.
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
- "${name}" must be an integer, but got ${JSON.stringify(value
- "${name}" must be greater than 0, but got ${JSON.stringify(v
- "${name}" must be <= ${max}, but got ${JSON.stringify(value)
- "strength" must be >= 0, but got ${JSON.stringify(r.strength
- "blur" must be >= 0, but got ${JSON.stringify(r.blur)}
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/02e01a8f2cbf7b67.
Report an issue: GitHub.