remotion-dev/remotion · error · TypeError

The "freeze" prop is not supported on <Html5Audio />. Use <S

Error message

The "freeze" prop is not supported on <Html5Audio />. Use <Sequence freeze={...}> to freeze media playback.

What it means

Html5Audio is Remotion's lower-level audio element that wraps a native <audio> tag for preview/rendering. The 'freeze' prop is intentionally unsupported on it because freezing media playback must be coordinated at the Sequence level, not on individual media tags. Passing freeze directly to Html5Audio is rejected at mount so users reach for the correct primitive: <Sequence freeze={...}>.

Source

Thrown at packages/core/src/audio/html5-audio.tsx:61

		pauseWhenBuffering,
		showInTimeline,
		onError: onRemotionError,
		freeze,
		...otherProps
	} = propsWithFreeze;
	const {loop, freeze: _freeze, ...propsOtherThanLoop} = propsWithFreeze;
	const {fps} = useVideoConfig();
	const environment = useRemotionEnvironment();
	const shouldPauseWhenBuffering = resolveV5Default(pauseWhenBuffering);

	if (environment.isClientSideRendering) {
		throw new Error(
			'<Html5Audio> is not supported in @remotion/web-renderer. Use <Audio> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations',
		);
	}

	if (typeof freeze !== 'undefined') {
		throw new TypeError(
			'The "freeze" prop is not supported on <Html5Audio />. Use <Sequence freeze={...}> to freeze media playback.',
		);
	}

	const {durations, setDurations} = useContext(DurationsContext);
	if (typeof props.src !== 'string') {
		throw new TypeError(
			`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(
				props.src,
			)} instead.`,
		);
	}

	const preloadedSrc = usePreload(props.src);

	const onError: React.ReactEventHandler<HTMLAudioElement> = useCallback(
		(e) => {
			// eslint-disable-next-line no-console

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Remove the freeze prop from <Html5Audio> and wrap it in <Sequence freeze={frame}>...<Html5Audio .../>...</Sequence> instead.
  2. If the prop arrived via a spread, destructure freeze out before passing the rest to <Html5Audio>.
  3. Audit shared media-prop objects and split freeze out for audio consumers.

Example fix

// before
<Html5Audio src={audioUrl} freeze />

// after
<Sequence freeze={frame}>
  <Html5Audio src={audioUrl} />
</Sequence>
Defensive patterns

Strategy: type-guard

Validate before calling

const isHtml5AudioProps = (p: Record<string, unknown>): boolean =>
  !('freeze' in p) || p.freeze === undefined;
if (!isHtml5AudioProps(props)) {
  // strip freeze or wrap in <Sequence freeze>
}

Type guard

const isFreezeFree = (
  p: Record<string, unknown>,
): p is Omit<typeof p, 'freeze'> => !('freeze' in p) || p.freeze === undefined;

Prevention

When it happens

Trigger: Rendering <Html5Audio src={...} freeze /> or <Html5Audio src={...} freeze={true} />. Also triggered by spreading an object that contains a freeze key into <Html5Audio {...spread} />, or by copying props from a <Video>/<Img> element (which do accept freeze) onto an audio element.

Common situations: Porting a <Video freeze> snippet to audio; using a shared prop object across media types; upgrading from a version where freeze was silently ignored on audio; auto-generating JSX from a template that injects freeze on every media tag.

Related errors


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