remotion-dev/remotion · error · TypeError
outputs.${layer}.outputTarget must be arraybuffer or web-fs.
Error message
outputs.${layer}.outputTarget must be arraybuffer or web-fs. What it means
Each layer output's outputTarget field, if present, must be exactly 'arraybuffer' or 'web-fs'. Any other value (including other string targets or wrong types) is rejected with this TypeError so the library only commits to output sinks it supports.
Source
Thrown at packages/video-matting/src/separate-video-layers.ts:123
output,
}: {
layer: 'base' | 'foreground';
output: VideoLayerOutputOptions | undefined;
}) => {
if (output === undefined) {
return;
}
if (!output || typeof output !== 'object' || Array.isArray(output)) {
throw new TypeError(`outputs.${layer} must be an object.`);
}
if (
output.outputTarget !== undefined &&
output.outputTarget !== 'arraybuffer' &&
output.outputTarget !== 'web-fs'
) {
throw new TypeError(
`outputs.${layer}.outputTarget must be arraybuffer or web-fs.`,
);
}
if (
output.outputTarget !== undefined &&
output.outputWritable !== undefined
) {
throw new TypeError(
`outputs.${layer} cannot specify both outputTarget and outputWritable.`,
);
}
if (output.outputWritable !== undefined) {
if (
typeof WritableStream === 'undefined' ||
!(output.outputWritable instanceof WritableStream)
) {View on GitHub (pinned to b2f4e34732)
Solutions
- Set outputTarget to 'arraybuffer' to receive an ArrayBuffer result.
- Set outputTarget to 'web-fs' to write via the File System Access API.
- Fix casing/typos ('arraybuffer' is all-lowercase).
- Use outputWritable instead if you want to pipe into your own sink.
Example fix
// before
outputs: {video: {outputTarget: 'file'}}
// after
outputs: {video: {outputTarget: 'arraybuffer'}} Defensive patterns
Strategy: type-guard
Validate before calling
const VALID = ['arraybuffer', 'web-fs'] as const;
if (out.outputTarget !== undefined && !VALID.includes(out.outputTarget)) throw new TypeError('bad outputTarget'); Type guard
const isOutputTarget = (v: unknown): v is 'arraybuffer' | 'web-fs' => v === 'arraybuffer' || v === 'web-fs';
Try / catch
try { await separateVideoLayers(opts); } catch (e) { if (e instanceof TypeError && e.message.includes('outputTarget')) { console.error('outputTarget must be arraybuffer or web-fs'); } throw e; } Prevention
- Only use the two documented target strings
- Watch for casing mistakes ('arrayBuffer' is invalid)
- Prefer a typed union so invalid strings fail at compile time
When it happens
Trigger: Passing {outputTarget: 'file'}, {outputTarget: 'blob'}, {outputTarget: 'stream'}, or a non-string value in a layer's output config.
Common situations: Copy-pasting target names from another library's API; assuming Node-style 'file' targets work in the browser build; typos like 'arrayBuffer' (wrong case).
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- "${name}" must be ${formatEnum(variants)}, but got ${JSON.st
- "direction" must be ${formatEnum(WAVE_DIRECTIONS)}, but got
- "${name}" must be one of ${variants.join(', ')}
- Value for ${JSON.stringify(key)} must be one of ${Object.key
- Argument missing for parameter "frame"
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/c85dc187e7aa449f.
Report an issue: GitHub.