remotion-dev/remotion · error · TypeError

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

Error message

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

What it means

Thrown by validateDirection in the Lines effect when direction is present but is not one of the two allowed literals 'horizontal' or 'vertical'. undefined is accepted (defaults to 'horizontal'). The error message is built dynamically from LINE_DIRECTIONS via formatEnum, so it reads 'must be "horizontal" or "vertical"'.

Source

Thrown at packages/effects/src/lines.ts:205

			`"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' ||
		!LINE_DIRECTIONS.includes(direction as LinesDirection)
	) {
		throw new TypeError(
			`"direction" must be ${formatEnum(LINE_DIRECTIONS)}, but got ${JSON.stringify(direction)}`,
		);
	}
};

const validateLinesParams = (params: LinesParams): void => {
	assertEffectParamsObject(params, 'Lines');
	validateColors(params.colors);
	validateDirection(params.direction);
	assertOptionalFiniteNumber(params.thickness, 'thickness');
	assertOptionalFiniteNumber(params.gap, 'gap');
	assertOptionalFiniteNumber(params.angle, 'angle');
	assertOptionalFiniteNumber(params.offset, 'offset');
	assertOptionalBoolean(params.maskToSourceAlpha, 'maskToSourceAlpha');

	const thickness = params.thickness ?? DEFAULT_THICKNESS;
	const gap = params.gap ?? DEFAULT_GAP;
	validatePositive(thickness, 'thickness');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Use 'horizontal' or 'vertical' (the only valid LinesDirection values).
  2. If you need diagonal stripes, keep direction as horizontal/vertical and set the angle prop instead.
  3. Type the value as LinesDirection so the compiler rejects bad literals.

Example fix

// before
lines({ direction: 'diagonal' })

// after
lines({ direction: 'horizontal', angle: 45 })
Defensive patterns

Strategy: type-guard

Validate before calling

const LINES_DIRECTIONS = ['horizontal', 'vertical'] as const;
type LinesDirection = (typeof LINES_DIRECTIONS)[number];
const isLinesDirection = (v: unknown): v is LinesDirection =>
  typeof v === 'string' && (LINES_DIRECTIONS as readonly string[]).includes(v);

lines({ direction: isLinesDirection(d) ? d : 'horizontal' });

Type guard

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

Prevention

When it happens

Trigger: Calling lines({ direction: 'diagonal' }), lines({ direction: 'h' }), lines({ direction: 1 }), or any value whose type is not string or whose value is not in the tuple. Note the Lines effect also exposes an angle prop for rotation; direction only chooses stripe axis.

Common situations: Using a wrong enum literal, a typo, or passing a value loaded from untyped JSON/serialized config. Confusing direction with the angle prop.

Related errors


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