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
- Wrap the consuming subtree with `<PreviewOverrideProvider>{...}</PreviewOverrideProvider>` so the hook resolves a context value.
- 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.
- 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
- Mount PreviewOverrideProvider once at the (create) route layout root.
- Lint: forbid importing usePreviewOverride outside files under the provider's subtree.
- Add a storybook decorator + test wrapper that always mounts the provider.
- When using portals/dialogs, verify the React (not DOM) tree stays under the provider.
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
- usePreviewOverride must be used within a TypesetPreviewOverr
- useHistory must be used within HistoryProvider
- useLocks must be used within LocksProvider
- useHistory must be used within TypesetHistoryProvider
- useLocks must be used within LocksProvider
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/2c4ea6d228d4950f.
Report an issue: GitHub.