remotion-dev/remotion · error · Error

No ${mediaType} ref found

Error message

No ${mediaType} ref found

What it means

Inside useMediaPlayback's main useEffect, the hook asserts mediaRef.current is set before syncing playback. A null ref means the underlying <audio>/<video> element is not mounted at effect time — usually because the JSX never actually rendered the tag (conditional render, ref attached to the wrong node, or the element was unmounted between render and commit).

Source

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

	// and it is also in a useLayoutEffect.
	useLayoutEffect(() => {
		const playbackRateToSet = Math.max(0, playbackRate);
		if (
			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 action = getMediaSyncAction({
			duration: current.duration,
			currentTime: current.currentTime,
			paused: current.paused,
			ended: current.ended,
			desiredUnclampedTime,
			mediaTagTime: mediaTagCurrentTime.current.time,
			mediaTagLastUpdate: mediaTagCurrentTime.current.lastUpdate,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure the ref returned by Remotion is attached to the real <audio>/<video> DOM node and that node always mounts with the component.
  2. If you wrap <Video>/<Audio>, use React.forwardRef and forward the ref to the underlying media element.
  3. Remove conditional rendering that hides the media tag while the component is mounted.
  4. Reproduce in isolation: render just <Video src={url}/> with no wrapper to confirm the wrapper is the cause.

Example fix

// before
const MyVideo = ({src}) => {
  return <video src={src} />; // ref dropped
};

// after
const MyVideo = React.forwardRef(({src}, ref) => {
  return <video src={src} ref={ref} />;
});
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the ref is attached to a always-mounted element.
// In custom wrappers:
// const MyVideo = React.forwardRef((props, ref) => <video ref={ref} {...props} />);

Type guard

const isAttached = (ref: React.RefObject<Element | null>) => ref.current instanceof HTMLMediaElement;

Prevention

When it happens

Trigger: Forwarding the media ref to a node that is conditionally rendered and the condition was false; passing a ref object that is never attached; the element unmounting synchronously before the effect runs; custom Audio/Video wrappers that drop the ref.

Common situations: Building a custom media wrapper and forgetting to spread/forward the ref onto the underlying <video> tag; conditional rendering of the source element; SSR where the ref never attaches; refactoring that renamed the ref prop.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/1adee8636ef8bbc4. Report an issue: GitHub.