{"record":{"id":"1a2abc4c932982f8","repo":"shadcn-ui/ui","slug":"usecarousel-must-be-used-within-a-carousel-1a2abc","errorCode":null,"errorMessage":"useCarousel must be used within a <Carousel />","messagePattern":"useCarousel must be used within a <Carousel />","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/v4/registry/bases/radix/ui/carousel.tsx","lineNumber":39,"sourceCode":"  setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0]\n  api: ReturnType<typeof useEmblaCarousel>[1]\n  scrollPrev: () => void\n  scrollNext: () => void\n  canScrollPrev: boolean\n  canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n  const context = React.useContext(CarouselContext)\n\n  if (!context) {\n    throw new Error(\"useCarousel must be used within a <Carousel />\")\n  }\n\n  return context\n}\n\nfunction Carousel({\n  orientation = \"horizontal\",\n  opts,\n  setApi,\n  plugins,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n  const [carouselRef, api] = useEmblaCarousel(\n    {\n      ...opts,\n      axis: orientation === \"horizontal\" ? \"x\" : \"y\",","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/apps/v4/registry/bases/radix/ui/carousel.tsx#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n<CarouselPrevious />\n\n// after\n<Carousel>\n  <CarouselContent>\n    <CarouselItem>...</CarouselItem>\n  </CarouselContent>\n  <CarouselPrevious />\n</Carousel>","handlingStrategy":"validation","validationCode":"// Optional, non-throwing reader — call before relying on the hook\nimport { carouselContext } from \"./carousel\" // or re-create the context ref\nfunction useOptionalCarousel() {\n  return React.useContext(CarouselContext)\n}\n// guard at call site:\nconst ctx = useOptionalCarousel()\nif (!ctx) return null","typeGuard":"// True when a <Carousel> ancestor is present\nfunction useHasCarousel(): boolean {\n  return React.useContext(CarouselContext) !== null\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["react","context","carousel","radix"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}