remotion-dev/remotion · error · TypeError

outputs.base and outputs.foreground must not use the same ou

Error message

outputs.base and outputs.foreground must not use the same outputWritable.

What it means

Each layer's output must go to a distinct stream. If base and foreground both specify the same outputWritable instance, the two encoded tracks would interleave into one stream, so this TypeError is thrown.

Source

Thrown at packages/video-matting/src/separate-video-layers.ts:192

			Array.isArray(options.outputs))
	) {
		throw new TypeError('outputs must be an object.');
	}

	validateLayerOutputOptions({
		layer: 'base',
		output: options.outputs?.base,
	});
	validateLayerOutputOptions({
		layer: 'foreground',
		output: options.outputs?.foreground,
	});
	if (
		options.outputs?.base?.outputWritable !== undefined &&
		options.outputs.base.outputWritable ===
			options.outputs.foreground?.outputWritable
	) {
		throw new TypeError(
			'outputs.base and outputs.foreground must not use the same outputWritable.',
		);
	}

	getVideoMattingModelInfo(options.model ?? 'modnet');

	if (
		options.audio !== undefined &&
		!AUDIO_DESTINATIONS.includes(options.audio)
	) {
		throw new TypeError(
			'audio must be one of base, foreground, both, or none.',
		);
	}

	resolveVideoMattingQuality(options.videoBitrate ?? 'very-high');
	resolveVideoMattingQuality(options.audioBitrate ?? 'medium');

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Create two separate WritableStreams, one per layer
  2. Write to two files or two branches of a properly tee'd pipeline (tee produces READABLES, so pipe each branch through its own TransformStream)
  3. Omit outputWritable for one layer and use outputPath/default handling instead

Example fix

// before
const shared = new WritableStream();
await separateVideoLayers({ src, outputs: { base: { outputWritable: shared }, foreground: { outputWritable: shared } } });
// after
await separateVideoLayers({ src, outputs: { base: { outputWritable: new WritableStream() }, foreground: { outputWritable: new WritableStream() } } });
Defensive patterns

Strategy: validation

Validate before calling

if (outputs?.base?.outputWritable && outputs.base.outputWritable === outputs?.foreground?.outputWritable) throw new TypeError('base and foreground need distinct WritableStreams');

Try / catch

try { await separateVideoLayers({ src, outputs }); } catch (e) { if (e instanceof TypeError && e.message.includes('same outputWritable')) { /* create a second stream */ } else throw e; }

Prevention

When it happens

Trigger: Reusing one WritableStream (or one TransformStream's writable side) for both outputs.base.outputWritable and outputs.foreground.outputWritable.

Common situations: Building outputs programmatically with a single shared stream variable; intending to write both layers to one file; copy-paste of the same stream reference.

Related errors


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