{"record":{"id":"58a7b695871e59ab","repo":"shadcn-ui/ui","slug":"usemessagescroller-must-be-used-within-a-messagesc","errorCode":null,"errorMessage":"useMessageScroller must be used within a MessageScroller.","messagePattern":"useMessageScroller must be used within a MessageScroller\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react/src/message-scroller/components.tsx","lineNumber":27,"sourceCode":"  MessageScrollerItemProps,\n  MessageScrollerProps,\n  MessageScrollerProviderProps,\n  MessageScrollerRegisterMessage,\n  MessageScrollerViewportProps,\n} from \"./types\"\nimport { useMessageScrollerController } from \"./use-message-scroller-controller\"\nimport { useLatest } from \"./utils\"\n\nconst MessageScrollerContext =\n  React.createContext<MessageScrollerContextValue | null>(null)\nconst MessageScrollerItemContext =\n  React.createContext<MessageScrollerRegisterMessage | null>(null)\n\nfunction useMessageScrollerContext() {\n  const context = React.useContext(MessageScrollerContext)\n\n  if (!context) {\n    throw new Error(\"useMessageScroller must be used within a MessageScroller.\")\n  }\n\n  return context\n}\n\nfunction useMessageScrollerItemContext() {\n  const context = React.useContext(MessageScrollerItemContext)\n\n  if (!context) {\n    throw new Error(\n      \"MessageScrollerItem must be used within a MessageScroller.\"\n    )\n  }\n\n  return context\n}\n\nfunction useMessageScroller() {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/react/src/message-scroller/components.tsx#L9-L45","documentation":"useMessageScrollerContext reads MessageScrollerContext, which only <MessageScroller> populates (it renders the provider around its children with scrollToEnd/scrollToMessage/scrollToStart and the controller). Calling useMessageScroller (which delegates to useMessageScrollerContext) or any sub-component that consumes it outside a <MessageScroller> yields null context, so the hook throws to avoid returning undefined scroll controls.","triggerScenarios":"Calling useMessageScroller() in a component rendered outside <MessageScroller>; rendering MessageScroller sub-components in a portal/modal above the provider; splitting the message list out of the <MessageScroller> tree.","commonSituations":"Extracting a scroll-to-bottom button into a sibling component; Storybook stories rendering a single message outside the scroller; refactor that lifts children above the provider.","solutions":["Wrap the subtree in <MessageScroller>.","Move the component calling useMessageScroller back inside the <MessageScroller> tree.","Render isolated pieces within a <MessageScroller> in tests/stories."],"exampleFix":"// before\n<ScrollToBottomButton /> // calls useMessageScroller\n\n// after\n<MessageScroller>\n  <MessageList />\n  <ScrollToBottomButton />\n</MessageScroller>","handlingStrategy":"validation","validationCode":"function useOptionalMessageScroller() {\n  const ctx = React.useContext(MessageScrollerContext)\n  return ctx ?? null\n}\nconst ms = useOptionalMessageScroller()\nif (!ms) return null","typeGuard":"function useHasMessageScroller(): boolean {\n  return React.useContext(MessageScrollerContext) !== null\n}","tryCatchPattern":null,"preventionTips":["Always render components calling useMessageScroller inside <MessageScroller>.","Keep scroll controls colocated with the message list.","Render isolated pieces within <MessageScroller> in stories/tests."],"tags":["react","context","message-scroller"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}