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
- Create two separate WritableStreams, one per layer
- Write to two files or two branches of a properly tee'd pipeline (tee produces READABLES, so pipe each branch through its own TransformStream)
- 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
- Instantiate one stream per layer
- Never share stream references when building options programmatically
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
- outputs.${layer} cannot specify both outputTarget and output
- outputs.${layer}.outputWritable must be a WritableStream.
- outputs.${layer}.outputWritable must not already be locked.
- Emoji ${emoji} not found. Available emojis: ${emojis.map((e)
- The start and end values must be of the same type. Start val
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/8e157a8b3b9eb595.
Report an issue: GitHub.