remotion-dev/remotion · error · Error
outputTarget and outputWritable cannot both be specified for
Error message
outputTarget and outputWritable cannot both be specified for a video layer
What it means
createVideoLayerOutput rejects options where both outputTarget and outputWritable are provided, since a video layer output may have exactly one destination. The two options are mutually exclusive by design.
Source
Thrown at packages/video-matting/src/create-video-layer-output.ts:36
export type CreatedVideoLayerOutput<F extends OutputFormat> = {
output: Output<F, VideoLayerMediabunnyTarget>;
finalize: () => Promise<VideoLayerOutput>;
cancel: () => Promise<void>;
discard: () => Promise<void>;
};
export const createVideoLayerOutput = async <F extends OutputFormat>({
format,
options,
}: {
format: F;
options: VideoLayerOutputOptions | undefined;
}): Promise<CreatedVideoLayerOutput<F>> => {
if (
options?.outputTarget !== undefined &&
options.outputWritable !== undefined
) {
throw new Error(
'outputTarget and outputWritable cannot both be specified for a video layer',
);
}
let webFsTarget: WebFsVideoLayerTarget | null = null;
let target: VideoLayerMediabunnyTarget;
let outputMode: 'arraybuffer' | 'web-fs' | 'writable';
const outputWritable = options?.outputWritable;
let outputWritableWriter: WritableStreamDefaultWriter<StreamTargetChunk> | null =
null;
let outputWritableClosePromise: Promise<void> | null = null;
let outputWritableAbortPromise: Promise<void> | null = null;
let outputWritableWasClosed = false;
const getOutputWritableWriter = () => {
if (outputWritable === undefined) {
throw new Error('Expected a caller-provided output WritableStream');
}
View on GitHub (pinned to b2f4e34732)
Solutions
- Specify only outputTarget OR only outputWritable, not both
- When merging option objects, explicitly unset the unused key (undefined won't help — delete it or build the object conditionally)
- Pick outputWritable when you want a writable stream, outputTarget for file/URL targets
Example fix
// before
createVideoLayerOutput({outputTarget: target, outputWritable: writable})
// after
createVideoLayerOutput({outputWritable: writable}) Defensive patterns
Strategy: validation
Validate before calling
if (opts.outputTarget !== undefined && opts.outputWritable !== undefined) {
throw new Error('Specify only one of outputTarget / outputWritable');
} Type guard
const hasExactlyOneOutput = (o: {outputTarget?: unknown; outputWritable?: unknown}): boolean =>
(o.outputTarget !== undefined) !== (o.outputWritable !== undefined); Try / catch
try {
const out = await createVideoLayerOutput(options);
} catch (err) {
if (String(err).includes('cannot both be specified')) {
// strip one key and retry, e.g. prefer outputWritable
}
} Prevention
- Build options objects conditionally instead of spreading multiple defaults
- When migrating between outputTarget and outputWritable, remove the old key
- Type options so consumers see a union of the two shapes
- Sanitize config-derived option objects before passing them
When it happens
Trigger: Calling createVideoLayerOutput({outputTarget: ..., outputWritable: ...}) with both fields set in the options object.
Common situations: Merging config objects/spreading defaults where both keys end up defined; refactoring code that switched from one option to the other without removing the old key.
Related errors
- You have passed a volume of type ${typeof props.volume} to y
- You have passed a volume below 0 to your <${component} /> co
- You have passed a playbackRate of type ${typeof props.playba
- You have passed a playbackRate of ${props.playbackRate} to y
- 'preservePitch' must be a boolean or undefined but got '${ty
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/881d2bea23ed2034.
Report an issue: GitHub.