shadcn-ui/ui · error · Error
useCarousel must be used within a <Carousel />
Error message
useCarousel must be used within a <Carousel />
What it means
useCarousel reads React.useContext(CarouselContext). The only code that ever puts a non-null value into that context is <Carousel>, which renders <CarouselContext.Provider value={...}> around its children. If a component calls useCarousel (directly or through CarouselContent / CarouselPrevious / CarouselNext / CarouselDots, which all call it) without a <Carousel> ancestor, context resolves to null and the hook throws to fail fast instead of returning a half-formed API.
Source
Thrown at apps/v4/registry/bases/radix/ui/carousel.tsx:39
setApi?: (api: CarouselApi) => void
}
type CarouselContextProps = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
api: ReturnType<typeof useEmblaCarousel>[1]
scrollPrev: () => void
scrollNext: () => void
canScrollPrev: boolean
canScrollNext: boolean
} & CarouselProps
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
function useCarousel() {
const context = React.useContext(CarouselContext)
if (!context) {
throw new Error("useCarousel must be used within a <Carousel />")
}
return context
}
function Carousel({
orientation = "horizontal",
opts,
setApi,
plugins,
className,
children,
...props
}: React.ComponentProps<"div"> & CarouselProps) {
const [carouselRef, api] = useEmblaCarousel(
{
...opts,
axis: orientation === "horizontal" ? "x" : "y",View on GitHub (pinned to efac598707)
Solutions
- Wrap the offending subtree in <Carousel opts={...}>...</Carousel> so the provider is an ancestor.
- Move the component that calls useCarousel back inside the <Carousel> tree.
- For isolated tests/stories, render the sub-component inside a <Carousel> rather than bare.
Example fix
// before
<CarouselPrevious />
// after
<Carousel>
<CarouselContent>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
</Carousel> Defensive patterns
Strategy: validation
Validate before calling
// Optional, non-throwing reader — call before relying on the hook
import { carouselContext } from "./carousel" // or re-create the context ref
function useOptionalCarousel() {
return React.useContext(CarouselContext)
}
// guard at call site:
const ctx = useOptionalCarousel()
if (!ctx) return null Type guard
// True when a <Carousel> ancestor is present
function useHasCarousel(): boolean {
return React.useContext(CarouselContext) !== null
} Prevention
- Always render carousel sub-components inside <Carousel>; treat the wrapper as required.
- Colocate CarouselPrevious/Next with CarouselContent so they are never lifted out.
- Add a smoke test that renders each carousel piece inside <Carousel>.
- Use an ErrorBoundary only as a last-resort safety net — render throws should be prevented by tree structure, not caught.
When it happens
Trigger: Rendering any carousel sub-component (CarouselItem, CarouselContent, CarouselPrevious, CarouselNext) outside of a <Carousel> wrapper; copy-pasting only the inner markup; conditionally unmounting <Carousel> while keeping its children mounted; importing useCarousel in a standalone control.
Common situations: Extracting a carousel control into its own file and forgetting the wrapper; Storybook stories that render a single CarouselItem in isolation; refactors that lift children above the <Carousel> node.
Related errors
- useCarousel must be used within a <Carousel />
- useCarousel must be used within a <Carousel />
- useSidebar must be used within a SidebarProvider.
- useCarousel must be used within a <Carousel />
- ${component} must be used within a Questionnaire.Root compon
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/1a2abc4c932982f8.
Report an issue: GitHub.