{"record":{"id":"b724d6b6efd0a751","repo":"remotion-dev/remotion","slug":"timelinecontext-is-not-available-this-hook-must-b","errorCode":null,"errorMessage":"TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.","messagePattern":"TimelineContext 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":79,"sourceCode":"\tconst env = useRemotionEnvironment();\n\n\tif (!videoConfig) {\n\t\treturn typeof window === 'undefined'\n\t\t\t? 0\n\t\t\t: (window.remotion_initialFrame ?? 0);\n\t}\n\n\tconst unclamped =\n\t\tstate.frame[videoConfig.id] ??\n\t\t(env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));\n\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","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/timeline-position-state.ts#L61-L97","documentation":"useTimelineContext() reads Remotion's timeline React context, which is provided by <Player>, the Remotion Studio, or a <Composition>'s runtime tree. When the context is null the hook throws immediately, because there is no meaningful frame to return outside of a Remotion-driven render.","triggerScenarios":"Calling useTimelineContext(), useTimelinePosition(), usePlayingState(), or useTimelineSetFrame() from a component rendered outside any <Player>/<Composition> (e.g. in a Storybook story, a plain React app, or a unit test without a Player wrapper).","commonSituations":"Reusing a Remotion component in a non-Remotion React app; mounting a component in isolation for testing; version mismatches where the context provider comes from a different Remotion install than the hook.","solutions":["Render the component inside a <Player> or as a registered <Composition> component.","For tests, wrap the component in a <Player> with a dummy composition.","Run `npx remotion versions` to confirm all @remotion/* packages share one version."],"exampleFix":"// before\nrender(<MyRemotionComponent />);\n\n// after\nrender(\n  <Player\n    component={MyRemotionComponent}\n    durationInFrames={30}\n    fps={30}\n    width={640}\n    height={360}\n  />\n);","handlingStrategy":"validation","validationCode":"// Wrap standalone usage in a Player for tests/previews\nimport {Player} from '@remotion/player';\n\nrender(\n  <Player\n    component={MyComp}\n    durationInFrames={30}\n    fps={30}\n    width={640}\n    height={360}\n  />,\n);","typeGuard":null,"tryCatchPattern":"try {\n  const state = useTimelineContext();\n} catch (e) {\n  // not in a Player/Studio; fall back to a default frame\n}","preventionTips":["Only call timeline hooks from components rendered by <Player> or a <Composition>.","Keep Remotion components out of non-Remotion React trees, or split them.","Align @remotion/* versions; run `npx remotion versions` after upgrades."],"tags":["react","context","hook","player","composition"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}