tailwindlabs/headlessui · critical · Error
A <Transition /> is used but it is missing a `show={true | f
Error message
A <Transition /> is used but it is missing a `show={true | false}` prop. What it means
<Transition> (TransitionRootFn) is a controlled visibility component: it needs to know whether content is shown. show may be inferred from a parent open-closed provider (e.g. inside a Dialog that uses CloseProvider), but if after that inference show is still undefined, Headless UI throws because it cannot decide the initial state. This is a required-prop guard, not a runtime state error.
Source
Thrown at packages/@headlessui-react/src/components/transition/transition.tsx:525
let { show, appear = false, unmount = true, ...theirProps } = props as typeof props
let internalTransitionRef = useRef<HTMLElement | null>(null)
let requiresRef = shouldForwardRef(props)
let transitionRef = useSyncRefs(
...(requiresRef ? [internalTransitionRef, ref] : ref === null ? [] : [ref])
)
// The TransitionChild will also call this hook, and we have to make sure that we are ready.
useServerHandoffComplete()
let usesOpenClosedState = useOpenClosed()
if (show === undefined && usesOpenClosedState !== null) {
show = (usesOpenClosedState & State.Open) === State.Open
}
if (show === undefined) {
throw new Error('A <Transition /> is used but it is missing a `show={true | false}` prop.')
}
let [state, setState] = useState(show ? TreeStates.Visible : TreeStates.Hidden)
let nestingBag = useNesting(() => {
if (show) return
setState(TreeStates.Hidden)
})
let [initial, setInitial] = useState(true)
// Change the `initial` value
let changes = useRef([show])
useIsoMorphicEffect(() => {
// We can skip this effect
if (initial === false) {
return
}View on GitHub (pinned to eea57cf46f)
Solutions
- Add the show prop: <Transition show={isOpen} ...>
- Ensure the value passed to show is a boolean, default it: show={isOpen ?? false}
- If inside a Dialog, either rely on Dialog's open state (render Transition as a Dialog child) or pass show explicitly
- For always-on CSS transitions without visibility control, use plain CSS classes instead of Transition
Example fix
// before
<Transition enter="transition" enterFrom="opacity-0">
<div>Content</div>
</Transition>
// after
<Transition show={isOpen} enter="transition" enterFrom="opacity-0">
<div>Content</div>
</Transition> Defensive patterns
Strategy: type-guard
Validate before calling
const show = maybeShow ?? false;
<Transition show={show} ...>...</Transition> Type guard
const hasShowProp = (p) => typeof p.show === 'boolean';
Prevention
- Always pass an explicit boolean to show
- Default unset state: show={isOpen ?? false}
- Don't strip props when spreading wrappers around Transition
When it happens
Trigger: Rendering <Transition> or <Transition.Root> with no show prop and no surrounding open/closed context provider; passing show={undefined} due to conditional props or an unset variable; using <Transition appear> without show expecting it to behave like CSS-only animations.
Common situations: Copy-pasting a Transition example and deleting the show prop; wiring show to state that is undefined at first render (lazy-initialized stores); refactoring from Transition.Child to Transition without adding show; version differences in Dialog-provided open state inference.
Related errors
- You provided an `onClose` prop to the `Dialog`, but the valu
- A <Transition /> is used but it is missing a `:show="true |
- You have to provide an `open` and an `onClose` prop to the `
- You provided an `onClose` prop to the `Dialog`, but forgot a
- You provided an `open` prop to the `Dialog`, but forgot an `
AI-assisted analysis of tailwindlabs/headlessui@eea57cf46f (2026-08-28).
Data as JSON: /api/errors/8422e55faf869e74.
Report an issue: GitHub.