remotion-dev/remotion · error · Error

`_experimentalKeepAudioContextAlive` cannot be changed dynam

Error message

`_experimentalKeepAudioContextAlive` cannot be changed dynamically.

What it means

_experimentalKeepAudioContextAlive is a Player-level flag that controls whether the Web Audio AudioContext stays running while silenced. Because the AudioContext and its scheduling are initialized once, flipping this flag mid-session is not supported. Remotion captures the first value in a ref and throws on any subsequent render that passes a different value.

Source

Thrown at packages/core/src/audio/shared-audio-tags.tsx:243

		window.remotion_sampleRate = sampleRate;
	}, [sampleRate]);

	const ctxAndGain = useSingletonAudioContext({
		logLevel,
		latencyHint: audioLatencyHint,
		audioEnabled,
		sampleRate,
	});
	const audioContextIsPlayingEventually = useRef(false);
	const initialExperimentalKeepAudioContextAlive = useRef(
		_experimentalKeepAudioContextAlive,
	);

	if (
		initialExperimentalKeepAudioContextAlive.current !==
		_experimentalKeepAudioContextAlive
	) {
		throw new Error(
			'`_experimentalKeepAudioContextAlive` cannot be changed dynamically.',
		);
	}

	const isResuming = useRef<AudioContextResumeAttempt | null>(null);
	const nextResumeAttemptId = useRef(0);

	const audioSyncAnchor = useMemo(() => ({value: 0}), []);

	const audioSyncAnchorListeners = useRef<AudioSyncAnchorListener[]>([]);
	const audioSyncAnchorEmitter: AudioSyncAnchorEmitter = useMemo(() => {
		return {
			dispatch: (event) => {
				audioSyncAnchorListeners.current.forEach((l) => l(event));
			},
			subscribe: (listener) => {
				audioSyncAnchorListeners.current.push(listener);
				return {

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Treat _experimentalKeepAudioContextAlive as a mount-time constant: decide it once and never change it for the Player's lifetime.
  2. If you need different behavior, unmount and remount the Player with a key that changes with the flag (key={String(flag)}).
  3. Remove the dynamic binding and pass a fixed boolean literal.

Example fix

// before
<Player _experimentalKeepAudioContextAlive={keepAlive} ... />

// after
<Player key={String(keepAlive)} _experimentalKeepAudioContextAlive={keepAlive} ... />
Defensive patterns

Strategy: validation

Validate before calling

const FLAG = true; // decide once
// <Player _experimentalKeepAudioContextAlive={FLAG} key={String(FLAG)} .../>

Prevention

When it happens

Trigger: Passing <Player _experimentalKeepAudioContextAlive={toggle} /> where toggle is React state that changes between true and false. Also triggered by a parent re-rendering the Player with a different flag value derived from props/context.

Common situations: Wiring the flag to a UI toggle; reading it from a config that hot-reloads with a different value in Studio; conditional flag based on a feature-toggle that flips during a session.

Related errors


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