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-consoleView on GitHub (pinned to 78fe4bb3fd)
Solutions
- Remove the freeze prop from <Html5Audio> and wrap it in <Sequence freeze={frame}>...<Html5Audio .../>...</Sequence> instead.
- If the prop arrived via a spread, destructure freeze out before passing the rest to <Html5Audio>.
- 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
- Never copy media props from <Video>/<Img> onto <Html5Audio> without filtering freeze.
- Keep audio-specific prop objects separate from video prop objects.
- Use TypeScript's exactOptionalPropertyTypes to surface unwanted freeze at compile time.
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
- The `<Html5Audio>` tag requires a string for `src`, but got
- Tried to simultaneously mount ${numberOfAudioTags + 1} <Html
- No 'src' was passed to <Html5Audio>.
- `_experimentalKeepAudioContextAlive` cannot be changed dynam
- The number of shared audio tags has changed dynamically. Onc
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/16123b9217d63abb.
Report an issue: GitHub.