{"record":{"id":"2ea490fe63923046","repo":"tailwindlabs/headlessui","slug":"a-transition-child-is-used-but-it-is-missing-a","errorCode":null,"errorMessage":"A <Transition.Child /> is used but it is missing a parent <Transition /> or <Transition.Root />.","messagePattern":"A <Transition\\.Child /> is used but it is missing a parent <Transition /> or <Transition\\.Root />\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@headlessui-react/src/components/transition/transition.tsx","lineNumber":129,"sourceCode":"  afterLeave?: () => void\n}\n\ntype TransitionChildPropsWeControl = never\n\nexport type TransitionChildProps<TTag extends ReactTag> = Props<\n  TTag,\n  TransitionChildRenderPropArg,\n  TransitionChildPropsWeControl,\n  PropsForFeatures<typeof TransitionChildRenderFeatures> &\n    TransitionClasses &\n    TransitionEvents & { transition?: boolean; appear?: boolean }\n>\n\nfunction useTransitionContext() {\n  let context = useContext(TransitionContext)\n\n  if (context === null) {\n    throw new Error(\n      'A <Transition.Child /> is used but it is missing a parent <Transition /> or <Transition.Root />.'\n    )\n  }\n\n  return context\n}\n\nfunction useParentNesting() {\n  let context = useContext(NestingContext)\n\n  if (context === null) {\n    throw new Error(\n      'A <Transition.Child /> is used but it is missing a parent <Transition /> or <Transition.Root />.'\n    )\n  }\n\n  return context\n}","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/tailwindlabs/headlessui/blob/eea57cf46fd6767ed1059012f7073b88eb159fba/packages/@headlessui-react/src/components/transition/transition.tsx#L111-L147","documentation":"<Transition.Child> must be rendered inside a <Transition> or <Transition.Root> because it reads shared transition state (show/appear/initial) from React context. useTransitionContext consumes that context and throws when it is null, meaning no parent Transition provided it. This guards against children that would otherwise animate incorrectly or not at all.","triggerScenarios":"Rendering <Transition.Child> as a sibling or outside of <Transition.Root>; using Dialog backdrop/content directly as Transition.Child without the wrapping Transition (older Headless UI v1 pattern); accidentally replacing the parent <Transition.Root show={...}> with a plain <div> during refactor; HOC/portals that render the child outside the provider tree.","commonSituations":"Migrating Headless UI v0 → v1 code where Dialog + Transition composition changed; wrapping Transition children in an extra element that breaks the provider chain; copy-pasting a Transition.Child snippet into a component that lacks the Transition wrapper.","solutions":["Wrap the Transition.Child elements in <Transition.Root show={isOpen}> (or <Transition show={isOpen}>)","If you don't need a transition, replace Transition.Child with a plain element or Dialog backdrop/panel directly","If you meant a standalone transition, use <Transition> itself instead of <Transition.Child>","Check that you didn't accidentally render the children through a portal or extracted component outside the Transition tree"],"exampleFix":"// before\n<Transition.Child\n  as={Fragment}\n  enter=\"ease-out duration-300\"\n  enterFrom=\"opacity-0\"\n>\n  <div className=\"fixed inset-0 bg-black\" />\n</Transition.Child>\n\n// after\n<Transition.Root show={isOpen} as={Fragment}>\n  <Transition.Child as={Fragment} enter=\"ease-out duration-300\" enterFrom=\"opacity-0\">\n    <div className=\"fixed inset-0 bg-black\" />\n  </Transition.Child>\n</Transition.Root>","handlingStrategy":"validation","validationCode":"import { Transition } from '@headlessui/react';\n// Always structure JSX so Transition.Child is lexically inside Transition.Root\nconst tree = (\n  <Transition.Root show={open}>\n    <Transition.Child as={Fragment}>...</Transition.Child>\n  </Transition.Root>\n);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Transition.Root and its Transition.Children in the same component/file","Codemod/lint against bare Transition.Child without a Transition ancestor","If unsure, use plain elements instead of Transition.Child"],"tags":["headlessui","react","transition","context","component-hierarchy"],"backgroundTag":"missing-context-provider","analyzedSha":"eea57cf46fd6767ed1059012f7073b88eb159fba","analyzedAt":"2026-08-28T19:22:46.163Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}