{"record":{"id":"d705340c71f85510","repo":"remotion-dev/remotion","slug":"expected-an-in-memory-output-target","errorCode":null,"errorMessage":"Expected an in-memory output target","messagePattern":"Expected an in-memory output target","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/create-video-layer-output.ts","lineNumber":269,"sourceCode":"\n\t\t\t\t\tlet blobPromise: Promise<Blob> | null = null;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdispose: discard,\n\t\t\t\t\t\tgetBlob: () => {\n\t\t\t\t\t\t\tblobPromise ??= (async () => {\n\t\t\t\t\t\t\t\tconst file = await webFsTarget.getBlob();\n\t\t\t\t\t\t\t\tconst buffer = await file.arrayBuffer();\n\t\t\t\t\t\t\t\treturn new Blob([buffer], {type: mimeType});\n\t\t\t\t\t\t\t})();\n\n\t\t\t\t\t\t\treturn blobPromise;\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (!(target instanceof BufferTarget)) {\n\t\t\t\t\tthrow new Error('Expected an in-memory output target');\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tdispose: () => Promise.resolve(),\n\t\t\t\t\tgetBlob: () => {\n\t\t\t\t\t\tif (target.buffer === null) {\n\t\t\t\t\t\t\treturn Promise.reject(new Error('The resulting buffer is empty'));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn Promise.resolve(new Blob([target.buffer], {type: mimeType}));\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tawait Promise.allSettled([cancelMediabunnyOutput(), discard()]);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t})();\n","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/create-video-layer-output.ts#L251-L287","documentation":"Thrown in finalize() when the output is in default (in-memory) mode but the mediabunny output's target is not a BufferTarget, so no blob can be read from memory. The wrapper requires an in-memory BufferTarget to expose getBlob().","triggerScenarios":"Creating the output without outputMode 'writable'/'web-fs' but attaching a StreamTarget or custom target instead of BufferTarget.","commonSituations":"Copy-pasted Output configuration from a streaming example; a refactor switched to StreamTarget for progress but getBlob() is still expected; target passed as null.","solutions":["Construct the mediabunny Output with new BufferTarget() when you intend to read the result via getBlob()","Or switch the layer output to 'writable'/'web-fs' mode to match the actual target","Inspect output.target instanceof BufferTarget before finalizing"],"exampleFix":"// before\nconst output = new Output({target: new StreamTarget(stream)});\nconst blob = await createVideoLayerOutput({output}).finalize();\n// after\nconst output = new Output({target: new BufferTarget()});\nconst blob = await createVideoLayerOutput({output}).finalize();","handlingStrategy":"type-guard","validationCode":"import {BufferTarget} from 'mediabunny';\nif (!(output.target instanceof BufferTarget)) {\n  throw new Error('getBlob() requires a BufferTarget');\n}\n","typeGuard":"const isInMemory = (output: {target: unknown}): output is {target: BufferTarget} =>\n  output.target instanceof BufferTarget;\n","tryCatchPattern":"try {\n  await layerOutput.finalize();\n} catch (e) {\n  if ((e as Error).message === 'Expected an in-memory output target') {\n    // switch to writable/web-fs mode or re-create output with BufferTarget\n  }\n  throw e;\n}\n","preventionTips":["Use BufferTarget whenever you need getBlob()","Derive outputMode from the target type, not separately","Document which target each output mode expects"],"tags":["mediabunny","buffer-target","type-mismatch"],"backgroundTag":"incompatible-source-type","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"}