shadcn-ui/ui · error · Error

useMessageScroller must be used within a MessageScroller.

Error message

useMessageScroller must be used within a MessageScroller.

What it means

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.

Source

Thrown at packages/react/src/message-scroller/components.tsx:27

  MessageScrollerItemProps,
  MessageScrollerProps,
  MessageScrollerProviderProps,
  MessageScrollerRegisterMessage,
  MessageScrollerViewportProps,
} from "./types"
import { useMessageScrollerController } from "./use-message-scroller-controller"
import { useLatest } from "./utils"

const MessageScrollerContext =
  React.createContext<MessageScrollerContextValue | null>(null)
const MessageScrollerItemContext =
  React.createContext<MessageScrollerRegisterMessage | null>(null)

function useMessageScrollerContext() {
  const context = React.useContext(MessageScrollerContext)

  if (!context) {
    throw new Error("useMessageScroller must be used within a MessageScroller.")
  }

  return context
}

function useMessageScrollerItemContext() {
  const context = React.useContext(MessageScrollerItemContext)

  if (!context) {
    throw new Error(
      "MessageScrollerItem must be used within a MessageScroller."
    )
  }

  return context
}

function useMessageScroller() {

View on GitHub (pinned to efac598707)

Solutions

  1. Wrap the subtree in <MessageScroller>.
  2. Move the component calling useMessageScroller back inside the <MessageScroller> tree.
  3. Render isolated pieces within a <MessageScroller> in tests/stories.

Example fix

// before
<ScrollToBottomButton /> // calls useMessageScroller

// after
<MessageScroller>
  <MessageList />
  <ScrollToBottomButton />
</MessageScroller>
Defensive patterns

Strategy: validation

Validate before calling

function useOptionalMessageScroller() {
  const ctx = React.useContext(MessageScrollerContext)
  return ctx ?? null
}
const ms = useOptionalMessageScroller()
if (!ms) return null

Type guard

function useHasMessageScroller(): boolean {
  return React.useContext(MessageScrollerContext) !== null
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/58a7b695871e59ab. Report an issue: GitHub.