remotion-dev/remotion · error · TypeError

"direction" must be ${formatEnum(WAVE_DIRECTIONS)}, but got

Error message

"direction" must be ${formatEnum(WAVE_DIRECTIONS)}, but got ${JSON.stringify(direction)}

What it means

Thrown by validateDirection() during waves() effect param validation. The waves effect accepts only 'horizontal' or 'vertical' as the direction value. This TypeError fires when direction is a string that is neither of those, or when it is a non-string type. The error message lists the allowed values via formatEnum(WAVE_DIRECTIONS).

Source

Thrown at packages/effects/src/waves.ts:250

			`"colors" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`,
		);
	}

	for (let i = 0; i < colors.length; i++) {
		assertRequiredColor(colors[i], `colors[${i}]`);
	}
};

const validateDirection = (direction: unknown): void => {
	if (direction === undefined) {
		return;
	}

	if (
		typeof direction !== 'string' ||
		!WAVE_DIRECTIONS.includes(direction as WavesDirection)
	) {
		throw new TypeError(
			`"direction" must be ${formatEnum(WAVE_DIRECTIONS)}, but got ${JSON.stringify(direction)}`,
		);
	}
};

const validateWavesParams = (params: WavesParams): void => {
	assertEffectParamsObject(params, 'Waves');
	validateColors(params.colors);
	validateDirection(params.direction);
	assertOptionalFiniteNumber(params.thickness, 'thickness');
	assertOptionalFiniteNumber(params.gap, 'gap');
	assertOptionalFiniteNumber(params.angle, 'angle');
	assertOptionalFiniteNumber(params.offset, 'offset');
	assertOptionalFiniteNumber(params.amplitude, 'amplitude');
	assertOptionalFiniteNumber(params.wavelength, 'wavelength');
	assertOptionalFiniteNumber(params.phase, 'phase');
	assertOptionalBoolean(params.maskToSourceAlpha, 'maskToSourceAlpha');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Use exactly 'horizontal' or 'vertical' (lowercase, no typos).
  2. Use the WavesDirection type to get compile-time checking: import type {WavesDirection} from '@remotion/effects'.
  3. If direction comes from user input or data, validate/sanitize it before passing: const dir = ['horizontal','vertical'].includes(input) ? input : undefined.

Example fix

// before
import {waves} from '@remotion/effects';
waves({direction: 'h'})         // throws
waves({direction: 'Horizontal'}) // throws — case-sensitive
waves({direction: 0})           // throws — not a string

// after
waves({direction: 'horizontal'})  // valid
waves({direction: 'vertical'})    // valid

// with type safety
import type {WavesDirection} from '@remotion/effects';
const dir: WavesDirection = 'horizontal';
waves({direction: dir})
Defensive patterns

Strategy: type-guard

Validate before calling

import type {WavesDirection} from '@remotion/effects';

const VALID_DIRECTIONS: readonly WavesDirection[] = ['horizontal', 'vertical'];

const safeDirection = (d: unknown): WavesDirection | undefined =>
  typeof d === 'string' && (VALID_DIRECTIONS as readonly string[]).includes(d)
    ? (d as WavesDirection)
    : undefined;

waves({direction: safeDirection(userInput)}); // falls back to default if invalid

Type guard

import type {WavesDirection} from '@remotion/effects';

const isWavesDirection = (v: unknown): v is WavesDirection =>
  v === 'horizontal' || v === 'vertical';

Prevention

When it happens

Trigger: Called from validateWavesParams() at packages/effects/src/waves.ts:259 via validateDirection(params.direction). Fires when you pass waves({direction: 'left'}), waves({direction: 'h'}), waves({direction: 0}), or any other value besides 'horizontal' or 'vertical'. Omitting direction is valid (defaults to 'horizontal').

Common situations: Typo in the direction string (e.g., 'horizonal', 'Horizontal' with uppercase); using a numeric code (0/1) instead of the string enum; copying a direction value from a different effect that uses different enum values; case sensitivity surprise.

Related errors


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