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

  1. Specify only outputTarget OR only outputWritable, not both
  2. When merging option objects, explicitly unset the unused key (undefined won't help — delete it or build the object conditionally)
  3. 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

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


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