remotion-dev/remotion · error · TypeError
src must be a string, URL, or Blob.
Error message
src must be a string, URL, or Blob.
What it means
validateOptions for separateVideoLayers() requires options.src to identify the input video as a string path/URL, a URL object, or a Blob. Any other type (number, plain object, undefined) is rejected before the video is fetched or decoded.
Source
Thrown at packages/video-matting/src/separate-video-layers.ts:163
}
if (output.outputWritable.locked) {
throw new TypeError(
`outputs.${layer}.outputWritable must not already be locked.`,
);
}
}
};
const validateOptions = (options: SeparateVideoLayersOptions) => {
if (!options || typeof options !== 'object') {
throw new TypeError('separateVideoLayers() expects an options object.');
}
const isBlob = typeof Blob !== 'undefined' && options.src instanceof Blob;
const isUrl = options.src instanceof URL;
if (typeof options.src !== 'string' && !isUrl && !isBlob) {
throw new TypeError('src must be a string, URL, or Blob.');
}
if (typeof options.src === 'string' && options.src.length === 0) {
throw new TypeError('src must not be an empty string.');
}
if (
options.outputs !== undefined &&
(!options.outputs ||
typeof options.outputs !== 'object' ||
Array.isArray(options.outputs))
) {
throw new TypeError('outputs must be an object.');
}
validateLayerOutputOptions({
layer: 'base',
output: options.outputs?.base,View on GitHub (pinned to b2f4e34732)
Solutions
- Pass a string path/URL, a new URL(...), or a Blob/File
- Convert bytes to a Blob: new Blob([buffer], { type: 'video/mp4' })
- Read the src from the correct variable/property (e.g. el.src instead of el)
Example fix
// before
await separateVideoLayers({ src: fileBuffer });
// after
await separateVideoLayers({ src: new Blob([fileBuffer], { type: 'video/mp4' }) }); Defensive patterns
Strategy: type-guard
Validate before calling
function assertSrc(src) { const isBlob = typeof Blob !== 'undefined' && src instanceof Blob; if (typeof src !== 'string' && !(src instanceof URL) && !isBlob) throw new TypeError('src must be a string, URL, or Blob'); } Type guard
const isValidSrc = (v) => typeof v === 'string' || v instanceof URL || (typeof Blob !== 'undefined' && v instanceof Blob);
Try / catch
try { await separateVideoLayers({ src }); } catch (e) { if (e instanceof TypeError && e.message.includes('src must be a string, URL, or Blob')) { /* convert bytes to Blob or fix src */ } else throw e; } Prevention
- Convert raw buffers to Blob before passing
- Pass el.src (string), not the element itself
- Check src type in dev with an assert helper
When it happens
Trigger: Passing an ArrayBuffer/Uint8Array of video bytes; passing undefined because the variable was misnamed; passing a File is fine (File extends Blob) but a plain object is not; passing a URL string built from non-string parts.
Common situations: Reading video into memory as bytes and assuming the API takes buffers; passing document.querySelector(...).src (DOM element instead of string); typed config from an unvalidated source.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- No src passed
- The `<OffthreadVideo>` tag requires a string for `src`, but
- No `src` was passed to <OffthreadVideo>.
- No src passed
- No `src` was passed to <Audio>.
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/d7428221ea61f7cc.
Report an issue: GitHub.