{"record":{"id":"c00d530f7abf3773","repo":"remotion-dev/remotion","slug":"playbackratecontext-is-not-available-this-hook-mu","errorCode":null,"errorMessage":"PlaybackRateContext is not available. This hook must be used inside a <Player> or the Remotion Studio.","messagePattern":"PlaybackRateContext is not available\\. This hook must be used inside a <Player> or the Remotion Studio\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/timeline-position-state.ts","lineNumber":90,"sourceCode":"\n\treturn clampFrameToCompositionRange(unclamped, videoConfig.durationInFrames);\n};\n\nexport const useTimelineContext = (): TimelineContextValue => {\n\tconst state = useContext(TimelineContext);\n\tif (state === null) {\n\t\tthrow new Error(\n\t\t\t'TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.',\n\t\t);\n\t}\n\n\treturn state;\n};\n\nexport const usePlaybackRate = (): PlaybackRateContextValue => {\n\tconst state = useContext(PlaybackRateContext);\n\tif (state === null) {\n\t\tthrow new Error(\n\t\t\t'PlaybackRateContext is not available. This hook must be used inside a <Player> or the Remotion Studio.',\n\t\t);\n\t}\n\n\treturn state;\n};\n\nexport const useTimelinePosition = (): number => {\n\tconst state = useTimelineContext();\n\treturn useTimelinePositionFromContext(state);\n};\n\nexport const useAbsoluteTimelinePosition = (): number => {\n\tconst state = useContext(AbsoluteTimeContext);\n\tif (state === null) {\n\t\tthrow new Error(\n\t\t\t'AbsoluteTimeContext is not available. This hook must be used inside a <Player> or the Remotion Studio.',\n\t\t);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/timeline-position-state.ts#L72-L108","documentation":"usePlaybackRate() reads Remotion's PlaybackRate React context, which is only provided inside <Player> or the Remotion Studio. When the context is null the hook throws, because playback rate is meaningless without a Player-driven timeline.","triggerScenarios":"Calling usePlaybackRate() from a component rendered outside <Player>/Studio, or from a component that is sometimes mounted standalone (e.g. in a thumbnail or preview).","commonSituations":"Sharing a component between the Player and a static preview; calling the hook at the top level of a module instead of inside the rendered tree; version mismatch between Player and core.","solutions":["Only call usePlaybackRate() from components that are guaranteed to render inside <Player> or a <Composition>.","Split the component so the playback-rate-dependent logic lives in a child rendered only within the Player tree.","Run `npx remotion versions` to align package versions."],"exampleFix":"// before\nfunction Controls({standalone}) {\n  const rate = usePlaybackRate();\n  return <Toolbar rate={rate} />;\n}\n\n// after\nfunction Controls() {\n  return <Toolbar />;\n}\nfunction PlayerControls() {\n  const rate = usePlaybackRate();\n  return <Toolbar rate={rate} />;\n}","handlingStrategy":"validation","validationCode":"// Only call inside components guaranteed to be Player/Composition children\nconst useOptionalPlaybackRate = () => {\n  try {\n    return usePlaybackRate();\n  } catch {\n    return 1;\n  }\n};","typeGuard":null,"tryCatchPattern":"try {\n  return usePlaybackRate();\n} catch (e) {\n  if (/PlaybackRateContext/.test((e as Error).message)) return 1;\n  throw e;\n}","preventionTips":["Restrict usePlaybackRate() to components rendered by <Player>/Studio.","Split shared components so Player-only hooks live in a dedicated child.","Verify package version alignment after upgrades."],"tags":["react","context","hook","player","playback-rate"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}