{"record":{"id":"c4befa82da1d9e8c","repo":"remotion-dev/remotion","slug":"outputs-must-be-an-object","errorCode":null,"errorMessage":"outputs must be an object.","messagePattern":"outputs must be an object\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/separate-video-layers.ts","lineNumber":176,"sourceCode":"\t}\n\n\tconst isBlob = typeof Blob !== 'undefined' && options.src instanceof Blob;\n\tconst isUrl = options.src instanceof URL;\n\tif (typeof options.src !== 'string' && !isUrl && !isBlob) {\n\t\tthrow new TypeError('src must be a string, URL, or Blob.');\n\t}\n\n\tif (typeof options.src === 'string' && options.src.length === 0) {\n\t\tthrow new TypeError('src must not be an empty string.');\n\t}\n\n\tif (\n\t\toptions.outputs !== undefined &&\n\t\t(!options.outputs ||\n\t\t\ttypeof options.outputs !== 'object' ||\n\t\t\tArray.isArray(options.outputs))\n\t) {\n\t\tthrow new TypeError('outputs must be an object.');\n\t}\n\n\tvalidateLayerOutputOptions({\n\t\tlayer: 'base',\n\t\toutput: options.outputs?.base,\n\t});\n\tvalidateLayerOutputOptions({\n\t\tlayer: 'foreground',\n\t\toutput: options.outputs?.foreground,\n\t});\n\tif (\n\t\toptions.outputs?.base?.outputWritable !== undefined &&\n\t\toptions.outputs.base.outputWritable ===\n\t\t\toptions.outputs.foreground?.outputWritable\n\t) {\n\t\tthrow new TypeError(\n\t\t\t'outputs.base and outputs.foreground must not use the same outputWritable.',\n\t\t);","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/separate-video-layers.ts#L158-L194","documentation":"validateOptions for separateVideoLayers() checks that options.outputs, when provided, is a non-null object (and not an array). It maps foreground/base output targets by layer key, so a malformed outputs value would break per-layer validation and is rejected up front.","triggerScenarios":"Passing outputs: ['base','foreground'] (an array of layer names); passing null; JSON config where outputs is a list instead of a map.","commonSituations":"Misreading the API as taking a list of layers; config file authored with the wrong shape; YAML/JSON schema drift.","solutions":["Reshape to an object: { base: {...}, foreground: {...} }","Remove outputs to use defaults (if base-only output is acceptable)","Validate your loaded config's shape before calling"],"exampleFix":"// before\nawait separateVideoLayers({ src, outputs: [{ layer: 'base', outputPath: 'b.mp4' }] });\n// after\nawait separateVideoLayers({ src, outputs: { base: { outputPath: 'b.mp4' } } });","handlingStrategy":"validation","validationCode":"if (outputs !== undefined && (outputs === null || typeof outputs !== 'object' || Array.isArray(outputs))) throw new TypeError('outputs must be a plain object');","typeGuard":"const isOutputsObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try { await separateVideoLayers({ src, outputs }); } catch (e) { if (e instanceof TypeError && e.message.includes('outputs must be an object')) { /* reshape config */ } else throw e; }","preventionTips":["Author outputs as { base: {...}, foreground: {...} } maps","Validate JSON/YAML config shapes before invoking"],"tags":["validation","config-shape","type-mismatch"],"backgroundTag":"invalid-config-value","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}