remotion-dev/remotion · error · Error

No 'src' attribute was passed to the

Error message

No 'src' attribute was passed to the ${tagName} element.

What it means

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>).

Solutions

  1. Provide a valid src before the media component mounts.
  2. Render the component conditionally: `{url && <Video src={url} />}`.
  3. Default the src to a real asset path so it is never undefined.
  4. Audit custom wrappers to ensure src is forwarded to the underlying element.

Example fix

// before
<Video src={clip?.url} />

// after
{clip?.url ? <Video src={clip.url} /> : null}
Defensive patterns

Strategy: validation

Validate before calling

if (!src) {
  return null;
}
return <Video src={src} />;

Type guard

const isHtmlSrc = (s: unknown): s is string => typeof s === 'string' && s.length > 0;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-08-12). Data as JSON: /api/errors/02bc0354668512db. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/use-media-playback.ts:194

			mediaRef.current &&
			mediaRef.current.playbackRate !== playbackRateToSet
		) {
			mediaRef.current.playbackRate = playbackRateToSet;
		}

		if (mediaRef.current && mediaRef.current.preservesPitch !== preservePitch) {
			mediaRef.current.preservesPitch = preservePitch;
		}
	}, [mediaRef, playbackRate, preservePitch]);

	useEffect(() => {
		const tagName = mediaType === 'audio' ? '<Html5Audio>' : '<Html5Video>';
		if (!mediaRef.current) {
			throw new Error(`No ${mediaType} ref found`);
		}

		if (!src) {
			throw new Error(
				`No 'src' attribute was passed to the ${tagName} element.`,
			);
		}

		const {current} = mediaRef;
		const isMediaTagBufferingOrStalled = isMediaTagBuffering || isBuffering();
		let pauseReason: 'not-playing' | 'buffering' | null = null;
		if (!playing) {
			pauseReason = 'not-playing';
		} else if (playerBuffering && !isMediaTagBufferingOrStalled) {
			pauseReason = 'buffering';
		}

		if (!current.paused && pauseReason !== null) {
			playbackLogging({
				logLevel,
				tag: 'pause',
				message: `Pausing ${current.src} because ${getPauseReason({

View on GitHub (pinned to b2f4e34732)