remotion-dev/remotion · error · TypeError

forceTranscode must be a boolean.

Error message

forceTranscode must be a boolean.

What it means

prepareAudio() requires the forceTranscode option to be a boolean if supplied. This guard (a TypeError) ensures the internal option parsing never receives strings, undefined-as-string, or other coercible values that would silently change transcoding behavior. The check happens after video timestamp validation and before deciding whether the 'none' destination returns a no-op pipeline.

Source

Thrown at packages/video-matting/src/prepare-audio.ts:74

	audioQuality: Quality | null;
	forceTranscode: boolean;
}): Promise<PreparedVideoMattingAudio> => {
	if (!Number.isFinite(videoStartTimestamp)) {
		throw new TypeError('videoStartTimestamp must be a finite number.');
	}

	if (!Number.isFinite(videoEndTimestamp)) {
		throw new TypeError('videoEndTimestamp must be a finite number.');
	}

	if (videoEndTimestamp < videoStartTimestamp) {
		throw new RangeError(
			'videoEndTimestamp must be greater than or equal to videoStartTimestamp.',
		);
	}

	if (typeof forceTranscode !== 'boolean') {
		throw new TypeError('forceTranscode must be a boolean.');
	}

	if (destination === 'none') {
		return {
			prime: () => Promise.resolve(),
			writeAudioUntil: () => Promise.resolve(),
			finishAudio: () => Promise.resolve(),
			cancel: () => Promise.resolve(),
		};
	}

	const audioTrack = await input.getPrimaryAudioTrack();
	if (audioTrack === null) {
		return {
			prime: () => Promise.resolve(),
			writeAudioUntil: () => Promise.resolve(),
			finishAudio: () => Promise.resolve(),
			cancel: () => Promise.resolve(),

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Pass an actual boolean: forceTranscode: true or forceTranscode: false.
  2. If the value comes from user input, coerce with === 'true' comparison or omit the property entirely when not needed.
  3. Omit the forceTranscode key instead of passing null or undefined wrapped in a string.

Example fix

// before
await prepareAudio({input, forceTranscode: 'true'});
// after
await prepareAudio({input, forceTranscode: true});
Defensive patterns

Strategy: type-guard

Validate before calling

if (forceTranscode !== undefined && typeof forceTranscode !== 'boolean') throw new TypeError('forceTranscode must be boolean');

Type guard

const isBool = (v: unknown): v is boolean => typeof v === 'boolean';

Try / catch

try { await prepareAudio(opts); } catch (e) { if (e instanceof TypeError && /forceTranscode/.test(e.message)) { opts.forceTranscode = opts.forceTranscode === 'true'; return prepareAudio(opts); } throw e; }

Prevention

When it happens

Trigger: Calling prepareAudio({forceTranscode: 'true'}), forceTranscode: 1, or forceTranscode: null — any value whose typeof is not 'boolean'.

Common situations: Passing the value through from CLI args, query strings, or JSON where booleans arrive as strings; forgetting that forceTranscode is not optional-string; hand-editing config files without converting the type.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/32ac0177d1f1e1ea. Report an issue: GitHub.