remotion-dev/remotion · error · TypeError

"wavelength" must be > 0, but got ${JSON.stringify(resolved.

Error message

"wavelength" must be > 0, but got ${JSON.stringify(resolved.wavelength)}

What it means

TypeError thrown by wave's validateWaveParams when the resolved wavelength is <= 0. The check uses the resolved value (default 240), so it triggers only when an explicit zero or negative number is passed. assertOptionalFiniteNumber runs first, so non-numbers/NaN/Infinity are rejected earlier with a different message.

Source

Thrown at packages/effects/src/wave/index.ts:109

	if (
		params.direction !== undefined &&
		params.direction !== 'horizontal' &&
		params.direction !== 'vertical'
	) {
		throw new TypeError(
			`"direction" must be "horizontal" or "vertical", but got ${JSON.stringify(params.direction)}`,
		);
	}

	const resolved = resolve(params);
	if (resolved.amplitude < 0) {
		throw new TypeError(
			`"amplitude" must be >= 0, but got ${JSON.stringify(resolved.amplitude)}`,
		);
	}

	if (resolved.wavelength <= 0) {
		throw new TypeError(
			`"wavelength" must be > 0, but got ${JSON.stringify(resolved.wavelength)}`,
		);
	}
};

// Sine wave warp: displaces source UVs along the propagation axis. WebGL2 only.
export const wave = createEffect<WaveParams, WaveState>({
	type: 'dev.remotion.effects.wave',
	label: 'wave()',
	documentationLink: 'https://www.remotion.dev/docs/effects/wave',
	backend: 'webgl2',
	calculateKey: (params) => {
		const r = resolve(params);
		return `wave-${r.phase}-${r.direction}-${r.amplitude}-${r.wavelength}`;
	},
	setup: (target) => setupWave(target),
	apply: ({source, width, height, params, state}) => {
		const r = resolve(params);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass wavelength > 0 (a small positive floor like 1, or clamp with Math.max(1, value)).
  2. For frame-driven wavelength, clamp with Math.max(MIN_WAVELENGTH, value).
  3. If you want to flatten the wave, reduce amplitude to 0 rather than wavelength.
  4. Type wavelength as a positive number and assert it at the source.

Example fix

// before - derived wavelength crosses zero
const e = wave({wavelength: 240 - frame}); // hits 0 and below

// after - keep it strictly positive
const e = wave({wavelength: Math.max(1, 240 - frame)});
Defensive patterns

Strategy: validation

Validate before calling

import {wave} from '@remotion/effects';

const MIN_WAVELENGTH = 1;
const clampWavelength = (value: number): number => {
  if (!Number.isFinite(value)) {
    throw new TypeError(`wavelength must be a finite number, got ${value}`);
  }
  return Math.max(MIN_WAVELENGTH, value);
};

const wavelength = clampWavelength(rawWavelength);
const e = wave({amplitude: 60, wavelength});

Type guard

const isPositiveFinite = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v) && v > 0;

Try / catch

try {
  const e = wave({amplitude: 60, wavelength: rawWavelength});
} catch (err) {
  if (err instanceof TypeError) {
    console.error('Invalid wave wavelength:', rawWavelength, err);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling wave({wavelength: 0}), wave({wavelength: -50}), or passing a computed wavelength that lands at or below zero (e.g. a frame-based formula that decreases through zero). A wavelength of zero is mathematically invalid for the sine warp.

Common situations: Animation formulas that shrink wavelength toward/through zero; division-based derivations that yield zero; passing a value intended for a different parameter.

Related errors


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