{"record":{"id":"02bc0354668512db","repo":"remotion-dev/remotion","slug":"no-src-attribute-was-passed-to-the-tagname-el","errorCode":null,"errorMessage":"No 'src' attribute was passed to the ${tagName} element.","messagePattern":"No 'src' attribute was passed to the (.+?) element\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/use-media-playback.ts","lineNumber":222,"sourceCode":"\t\t\tmediaRef.current &&\n\t\t\tmediaRef.current.playbackRate !== playbackRateToSet\n\t\t) {\n\t\t\tmediaRef.current.playbackRate = playbackRateToSet;\n\t\t}\n\n\t\tif (mediaRef.current && mediaRef.current.preservesPitch !== preservePitch) {\n\t\t\tmediaRef.current.preservesPitch = preservePitch;\n\t\t}\n\t}, [mediaRef, playbackRate, preservePitch]);\n\n\tuseEffect(() => {\n\t\tconst tagName = mediaType === 'audio' ? '<Html5Audio>' : '<Html5Video>';\n\t\tif (!mediaRef.current) {\n\t\t\tthrow new Error(`No ${mediaType} ref found`);\n\t\t}\n\n\t\tif (!src) {\n\t\t\tthrow new Error(\n\t\t\t\t`No 'src' attribute was passed to the ${tagName} element.`,\n\t\t\t);\n\t\t}\n\n\t\tconst {current} = mediaRef;\n\n\t\tconst action = getMediaSyncAction({\n\t\t\tduration: current.duration,\n\t\t\tcurrentTime: current.currentTime,\n\t\t\tpaused: current.paused,\n\t\t\tended: current.ended,\n\t\t\tdesiredUnclampedTime,\n\t\t\tmediaTagTime: mediaTagCurrentTime.current.time,\n\t\t\tmediaTagLastUpdate: mediaTagCurrentTime.current.lastUpdate,\n\t\t\trvcTime: rvcCurrentTime.current?.time ?? null,\n\t\t\trvcLastUpdate: rvcCurrentTime.current?.lastUpdate ?? null,\n\t\t\tisVariableFpsVideo: Boolean(isVariableFpsVideoMap.current[src]),\n\t\t\tacceptableTimeShift: acceptableTimeShiftButLessThanDuration,","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/use-media-playback.ts#L204-L240","documentation":"Companion guard to 364: after confirming the media ref exists, useMediaPlayback checks that `src` is truthy and throws this if not. It exists because the playback-sync effect needs a src to compute seek times. Distinct from the timeline 'No src passed' guards because it fires in the playback effect path and names the underlying Html5 element (<Html5Audio>/<Html5Video>).","triggerScenarios":"Rendering <Audio>/<Video> in preview/Player mode with src undefined; src set to an empty string; src cleared after mount before the playback effect runs.","commonSituations":"Async-loaded source where the component mounts before the URL is known; optional src prop with no default; conditional playback where the source field is empty in some data rows.","solutions":["Provide a valid src before the media component mounts.","Render the component conditionally: `{url && <Video src={url} />}`.","Default the src to a real asset path so it is never undefined.","Audit custom wrappers to ensure src is forwarded to the underlying element."],"exampleFix":"// before\n<Video src={clip?.url} />\n\n// after\n{clip?.url ? <Video src={clip.url} /> : null}","handlingStrategy":"validation","validationCode":"if (!src) {\n  return null;\n}\nreturn <Video src={src} />;","typeGuard":"const isHtmlSrc = (s: unknown): s is string => typeof s === 'string' && s.length > 0;","tryCatchPattern":null,"preventionTips":["Render media elements conditionally on a validated non-empty src.","Forward src correctly through wrappers; do not drop or default it to undefined.","For async sources, mount the component only after resolution."],"tags":["remotion","media","src","html5","use-effect"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}