remotion-dev/remotion · error · TypeError

'preservePitch' must be a boolean or undefined but got '${ty

Error message

'preservePitch' must be a boolean or undefined but got '${typeof props.preservePitch}' instead

What it means

The <Audio>, <Video>, <Html5Video>, and <Html5Audio> components accept a `preservePitch` boolean prop that controls whether the audio pitch is preserved when `playbackRate` is not 1 (it maps to the HTML5 media element's preservesPitch feature). validateMediaProps rejects any value that is not a boolean or undefined so the underlying media element always receives a well-typed flag. This guards against silent coercion bugs where a truthy non-boolean would behave unexpectedly.

Source

Thrown at packages/core/src/validate-media-props.ts:51

		);
	}

	if (
		typeof props.playbackRate === 'number' &&
		(isNaN(props.playbackRate) ||
			!Number.isFinite(props.playbackRate) ||
			props.playbackRate <= 0)
	) {
		throw new TypeError(
			`You have passed a playbackRate of ${props.playbackRate} to your <${component} /> component. Playback rate must be a real number above 0.`,
		);
	}

	if (
		typeof props.preservePitch !== 'boolean' &&
		typeof props.preservePitch !== 'undefined'
	) {
		throw new TypeError(
			`'preservePitch' must be a boolean or undefined but got '${typeof props.preservePitch}' instead`,
		);
	}
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass preservePitch as a literal boolean or omit it: preservePitch={true} or preservePitch={false}.
  2. If the value comes from a string source, coerce explicitly before rendering: preservePitch={String(val).toLowerCase() === 'true'}.
  3. If the value comes from a number (0/1), convert: preservePitch={Boolean(numVal)}.
  4. Omit the prop entirely to accept the default (undefined, which lets the browser default apply).

Example fix

// before
<Video src={src} playbackRate={2} preservePitch="true" />
// after
<Video src={src} playbackRate={2} preservePitch={true} />
Defensive patterns

Strategy: type-guard

Validate before calling

if (preservePitch !== undefined && typeof preservePitch !== 'boolean') {
  throw new Error(`preservePitch must be boolean or undefined, got ${typeof preservePitch}`);
}

Type guard

const isPreservePitch = (v: unknown): v is boolean | undefined =>
  v === undefined || typeof v === 'boolean';

Prevention

When it happens

Trigger: Passing preservePitch as a string ("true", "false", "yes"), a number (0/1), or any object to <Audio>/<Video>/<Html5Video>/<Html5Audio>. Common when the prop is read from JSON/config files, URL query params, or API responses where booleans get stringified.

Common situations: Reading playback settings from a JSON config or environment variable that returns "true" as a string; spreading untyped props fetched from an API into a <Video> component; migrating from a custom player that used 1/0 for pitch flags.

Related errors


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