{"record":{"id":"22174464959ebb66","repo":"remotion-dev/remotion","slug":"experimentalkeepaudiocontextalive-cannot-be-cha","errorCode":null,"errorMessage":"`_experimentalKeepAudioContextAlive` cannot be changed dynamically.","messagePattern":"`_experimentalKeepAudioContextAlive` cannot be changed dynamically\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/audio/shared-audio-tags.tsx","lineNumber":243,"sourceCode":"\t\twindow.remotion_sampleRate = sampleRate;\n\t}, [sampleRate]);\n\n\tconst ctxAndGain = useSingletonAudioContext({\n\t\tlogLevel,\n\t\tlatencyHint: audioLatencyHint,\n\t\taudioEnabled,\n\t\tsampleRate,\n\t});\n\tconst audioContextIsPlayingEventually = useRef(false);\n\tconst initialExperimentalKeepAudioContextAlive = useRef(\n\t\t_experimentalKeepAudioContextAlive,\n\t);\n\n\tif (\n\t\tinitialExperimentalKeepAudioContextAlive.current !==\n\t\t_experimentalKeepAudioContextAlive\n\t) {\n\t\tthrow new Error(\n\t\t\t'`_experimentalKeepAudioContextAlive` cannot be changed dynamically.',\n\t\t);\n\t}\n\n\tconst isResuming = useRef<AudioContextResumeAttempt | null>(null);\n\tconst nextResumeAttemptId = useRef(0);\n\n\tconst audioSyncAnchor = useMemo(() => ({value: 0}), []);\n\n\tconst audioSyncAnchorListeners = useRef<AudioSyncAnchorListener[]>([]);\n\tconst audioSyncAnchorEmitter: AudioSyncAnchorEmitter = useMemo(() => {\n\t\treturn {\n\t\t\tdispatch: (event) => {\n\t\t\t\taudioSyncAnchorListeners.current.forEach((l) => l(event));\n\t\t\t},\n\t\t\tsubscribe: (listener) => {\n\t\t\t\taudioSyncAnchorListeners.current.push(listener);\n\t\t\t\treturn {","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/audio/shared-audio-tags.tsx#L225-L261","documentation":"_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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Treat _experimentalKeepAudioContextAlive as a mount-time constant: decide it once and never change it for the Player's lifetime.","If you need different behavior, unmount and remount the Player with a key that changes with the flag (key={String(flag)}).","Remove the dynamic binding and pass a fixed boolean literal."],"exampleFix":"// before\n<Player _experimentalKeepAudioContextAlive={keepAlive} ... />\n\n// after\n<Player key={String(keepAlive)} _experimentalKeepAudioContextAlive={keepAlive} ... />","handlingStrategy":"validation","validationCode":"const FLAG = true; // decide once\n// <Player _experimentalKeepAudioContextAlive={FLAG} key={String(FLAG)} .../>","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat _experimentalKeepAudioContextAlive as a build-time constant.","Do not bind it to React state that can change.","If behavior must change, remount the Player via key."],"tags":["audio","player","validation","react","lifecycle"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}