RocketChat/Rocket.Chat · warning

Failed to resume audio playback:

Error message

Failed to resume audio playback:

What it means

Client-side: the player's toggle handler called audio.play() to resume a paused track and the promise rejected. Unlike programmatic starts, this runs inside a user gesture, so the usual causes are media-level failures: source unloaded or expired (src removed, link expired), the fetch of media data aborted by a new load request, or the element left in a state where play() cannot start.

Source

Thrown at apps/meteor/client/providers/MediaPlayerProvider/MediaPlayerProvider.tsx:65

		if (trackRef.current?.id !== next.id) {
			setTrack(next);
			setCurrentTime(0);
			setDuration(0);
			audio.src = next.url;
			audio.load();
		}

		audio.playbackRate = playbackRate;
		audio.play().catch((err) => console.warn('Failed to start audio playback:', err));
	});

	const toggle = useStableCallback(() => {
		const audio = audioRef.current;
		if (!audio || !trackRef.current) {
			return;
		}
		if (audio.paused) {
			audio.play().catch((err) => console.warn('Failed to resume audio playback:', err));
		} else {
			audio.pause();
		}
	});

	const seek = useStableCallback((time: number) => {
		const audio = audioRef.current;
		if (!audio) {
			return;
		}
		audio.currentTime = Math.max(0, Math.min(time, audio.duration || time));
	});

	const cyclePlaybackRate = useStableCallback(() => {
		setPlaybackRate((rate) => {
			const idx = PLAYBACK_RATES.indexOf(rate as (typeof PLAYBACK_RATES)[number]);
			const nextRate = PLAYBACK_RATES[(idx + 1) % PLAYBACK_RATES.length];
			if (audioRef.current) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Check the err.name in console: AbortError is a benign race — retry play(); NotSupportedError means the source is bad
  2. Re-set audio.src with a fresh URL before resuming if links can expire
  3. Avoid starting a new load while a play() promise is pending; chain the operations instead
  4. For unrecoverable sources, surface an error state in the UI instead of retrying
Defensive patterns

Strategy: try-catch

Type guard

function isAbortError(err: unknown): err is DOMException {
	return err instanceof DOMException && err.name === 'AbortError';
}

Try / catch

audio.play().catch((err: unknown) => {
	if (isAbortError(err)) return; // benign: superseded by a new load request
	if (err instanceof DOMException && err.name === 'NotSupportedError') {
		showSourceErrorUI();
		return;
	}
	console.warn('Failed to resume audio playback:', err);
});

Prevention

When it happens

Trigger: Resuming after the underlying file URL expired; pressing play while a track switch is mid-load (AbortError: play() interrupted by a new load request); playbackRate or currentTime set to an unsupported value before resume; source removed from the element while paused.

Common situations: Audio attachments whose authenticated URLs expire during a long pause; quick toggle/track-change races; mobile browsers unloading media to save memory.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/f0788a76f32935af. Report an issue: GitHub.