{"record":{"id":"5ffab5ace2524b84","repo":"remotion-dev/remotion","slug":"usetimelineselectionitem-must-be-used-inside","errorCode":null,"errorMessage":"useTimelineSelectionItem must be used inside TimelineSelectionProvider","messagePattern":"useTimelineSelectionItem must be used inside TimelineSelectionProvider","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/Timeline/TimelineSelection.tsx","lineNumber":1654,"sourceCode":"\t\tselectionItem,\n\t\tuseSelectionOrder: true,\n\t});\n};\n\nconst useTimelineSelectionItem = <\n\tTSelectionItem extends TimelineSelection | null,\n>({\n\trevealInInspector,\n\tselectionItem,\n\tuseSelectionOrder,\n}: {\n\treadonly revealInInspector: boolean;\n\treadonly selectionItem: TSelectionItem;\n\treadonly useSelectionOrder: boolean;\n}) => {\n\tconst selectionContext = useContext(TimelineRowSelectionContext);\n\tif (selectionContext === null) {\n\t\tthrow new Error(\n\t\t\t'useTimelineSelectionItem must be used inside TimelineSelectionProvider',\n\t\t);\n\t}\n\n\tconst selectableTimelineItemsRef = useContext(SelectableTimelineItemsContext);\n\tconst selectionItemKey = useMemo(\n\t\t() =>\n\t\t\tselectionItem === null ? null : getTimelineSelectionKey(selectionItem),\n\t\t[selectionItem],\n\t);\n\tconst getSelectedState = useCallback((): TimelineSelectionState | null => {\n\t\tif (selectionItemKey === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst snapshot = selectionContext.getSnapshot();\n\t\treturn snapshot.selectedItems.some(\n\t\t\t(item) => getTimelineSelectionKey(item) === selectionItemKey,","sourceCodeStart":1636,"sourceCodeEnd":1672,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/components/Timeline/TimelineSelection.tsx#L1636-L1672","documentation":"useTimelineSelectionItem registers a Timeline item with the selection system. It reads TimelineRowSelectionContext and throws this error when the context is null, i.e. the hook is not used inside TimelineSelectionProvider.","triggerScenarios":"Rendering a Timeline item component (via the hook's wrapper props) outside a TimelineSelectionProvider — typically a custom item renderer extracted from the Timeline tree, or a provider removed during refactor.","commonSituations":"Custom Studio Timeline item components reused elsewhere in Studio; unit-testing a Timeline item in isolation without the provider; conditional rendering that places items in a portal outside the provider.","solutions":["Ensure the item component using the hook renders within <TimelineSelectionProvider>.","In tests, wrap the component with TimelineSelectionProvider in the render helper.","Check for React portals or memo boundaries that break context propagation and move the provider accordingly.","If building a custom item, accept the selection context via props instead of calling the hook outside the provider."],"exampleFix":"// before\nrender(<MyTimelineItem item={item} />);\n// after\nrender(\n  <TimelineSelectionProvider>\n    <MyTimelineItem item={item} />\n  </TimelineSelectionProvider>\n);","handlingStrategy":"validation","validationCode":"// ensure provider exists before rendering the item\n<TimelineSelectionProvider>{itemComponent}</TimelineSelectionProvider>","typeGuard":null,"tryCatchPattern":"try {\n  renderItem();\n} catch (e) {\n  if (e.message.includes('useTimelineSelectionItem must be used inside')) {\n    console.warn('Wrap the item in TimelineSelectionProvider');\n  } else throw e;\n}","preventionTips":["Wrap isolated Timeline item tests with TimelineSelectionProvider.","Avoid portals that break context ancestry for Timeline items.","Keep custom item renderers under the provider in the component tree."],"tags":["react","context","hooks","studio"],"backgroundTag":"missing-required-argument","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}