shadcn-ui/ui · error · Error

usePreviewOverride must be used within a PreviewOverrideProv

Error message

usePreviewOverride must be used within a PreviewOverrideProvider.

What it means

Standard React context guard. `usePreviewOverride` reads `PreviewOverrideActionsContext` via `React.useContext`; the context defaults to undefined/null, so calling the hook outside a mounted `<PreviewOverrideProvider>` throws immediately at render. The throw is intentional fail-fast: pickers rely on the stable setters the provider memoizes.

Source

Thrown at apps/v4/app/(app)/(create)/components/preview-override.tsx:104

    () => ({ setOverride, clearOverride }),
    [setOverride, clearOverride]
  )

  return (
    <PreviewOverrideActionsContext.Provider value={actions}>
      <PreviewOverrideValueContext.Provider value={override}>
        {children}
      </PreviewOverrideValueContext.Provider>
    </PreviewOverrideActionsContext.Provider>
  )
}

// For pickers: stable setters only, never re-renders on override changes.
export function usePreviewOverride() {
  const context = React.useContext(PreviewOverrideActionsContext)

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

  return context
}

// For the preview iframe host: the current override value.
export function usePreviewOverrideValue() {
  return React.useContext(PreviewOverrideValueContext)
}

View on GitHub (pinned to efac598707)

Solutions

  1. Wrap the consuming subtree with `<PreviewOverrideProvider>{...}</PreviewOverrideProvider>` so the hook resolves a context value.
  2. If the consumer is in a portal/dialog, ensure the portal's React tree (not just the DOM tree) is inside the provider, or pass the value via props instead.
  3. In tests/stories, add a decorator that mounts the provider around the component.

Example fix

// before
<MyPicker />

// after
<PreviewOverrideProvider>
  <MyPicker />
</PreviewOverrideProvider>
Defensive patterns

Strategy: type-guard

Validate before calling

// In tests/dev tools, assert the provider is in the tree before rendering a picker.
import { render } from "@testing-library/react"
function assertProvider(ui) {
  // Wrap unconditionally; the hook will throw only if a consumer is truly outside.
  return render(<PreviewOverrideProvider>{ui}</PreviewOverrideProvider>)
}

Type guard

import React from "react"
import { PreviewOverrideActionsContext } from "@/(app)/(create)/components/preview-override"
function isInPreviewOverrideProvider(): boolean {
  return React.useContext(PreviewOverrideActionsContext) != null
}
// usage: if (!isInPreviewOverrideProvider()) return <Fallback/>

Try / catch

try {
  return usePreviewOverride() // throws if outside provider
} catch (e) {
  if (e instanceof Error && e.message.includes("PreviewOverrideProvider")) {
    // Render a fallback or re-mount the provider.
  }
  throw e
}

Prevention

When it happens

Trigger: Rendering a component that calls `usePreviewOverride()` (or `usePreviewOverrideValue()`) anywhere not nested under `<PreviewOverrideProvider>` — e.g. a picker rendered in a route segment, a storybook story, or a test render without the provider tree. Also triggered by rendering the consumer in a portal whose tree is outside the provider.

Common situations: Reorganizing the (create) route layout and forgetting to wrap a subtree; adding a new picker component that calls the hook before threading the provider; unit tests that shallow-render the picker in isolation; HMR after moving the provider.

Related errors


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