{"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":194,"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\t\tconst isMediaTagBufferingOrStalled = isMediaTagBuffering || isBuffering();\n\t\tlet pauseReason: 'not-playing' | 'buffering' | null = null;\n\t\tif (!playing) {\n\t\t\tpauseReason = 'not-playing';\n\t\t} else if (playerBuffering && !isMediaTagBufferingOrStalled) {\n\t\t\tpauseReason = 'buffering';\n\t\t}\n\n\t\tif (!current.paused && pauseReason !== null) {\n\t\t\tplaybackLogging({\n\t\t\t\tlogLevel,\n\t\t\t\ttag: 'pause',\n\t\t\t\tmessage: `Pausing ${current.src} because ${getPauseReason({","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/core/src/use-media-playback.ts#L176-L212","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":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-08-12T17:18:50.444Z","contentChangedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}