tailwindlabs/headlessui · error · Error
Did you forget to passthrough the `ref` to the actual DOM no
Error message
Did you forget to passthrough the `ref` to the actual DOM node?
What it means
Headless UI Vue's <TransitionChild>/<Transition> requires the transition to be attached to a real DOM node. After resolving the container via `dom(container)`, the library checks whether the resolved node is an empty Vue comment placeholder (`Comment` node with empty data), which is what Vue renders when a component returns null/renders nothing. If so, the `ref` you were given was never forwarded to an actual element, so the transition has nothing to animate.
Source
Thrown at packages/@headlessui-vue/src/components/transitions/transition.ts:263
let enterFromClasses = splitClasses(props.enterFrom)
let enterToClasses = splitClasses(props.enterTo)
let enteredClasses = splitClasses(props.entered)
let leaveClasses = splitClasses(props.leave)
let leaveFromClasses = splitClasses(props.leaveFrom)
let leaveToClasses = splitClasses(props.leaveTo)
onMounted(() => {
watchEffect(() => {
if (state.value === TreeStates.Visible) {
let domElement = dom(container)
// When you return `null` from a component, the actual DOM reference will
// be an empty comment... This means that we can never check for the DOM
// node to be `null`. So instead we check for an empty comment.
let isEmptyDOMNode = domElement instanceof Comment && domElement.data === ''
if (isEmptyDOMNode) {
throw new Error('Did you forget to passthrough the `ref` to the actual DOM node?')
}
}
})
})
function executeTransition(onInvalidate: (cb: () => void) => void) {
// Skipping initial transition
let skip = initial.value && !appear.value
let node = dom(container)
if (!node || !(node instanceof HTMLElement)) return
if (skip) return
isTransitioning.value = true
if (show.value) beforeEnter()
if (!show.value) beforeLeave()
View on GitHub (pinned to eea57cf46f)
Solutions
- Ensure the component inside <TransitionChild> forwards the ref to its root element: accept `props` and spread them via `v-bind="attrs"` (see the `forwardRefs`/`useRender` helpers in headlessui-vue).
- Give the inner component a single root element so Vue attaches the forwarded ref/attrs automatically.
- If you don't need a wrapper, remove it and put the transition classes/props directly on a real element.
- Avoid `as="template"` when the children render to nothing or to multiple nodes.
Example fix
<!-- before -->
<TransitionChild as="template">
<MyPanel /> <!-- MyPanel never forwards the ref -->
</TransitionChild>
<!-- after -->
<!-- MyPanel.vue -->
<template><div v-bind="attrs"><slot /></div></template>
<script setup>
import { useAttrs } from 'vue'
let attrs = useAttrs()
</script> Defensive patterns
Strategy: validation
Validate before calling
// Before rendering, ensure the child of TransitionChild has a single real element root // e.g. check your wrapper component's template has exactly one element and forwards attrs
Prevention
- Give custom wrapper components inside transitions a single root element that binds v-bind="attrs".
- Avoid components returning null inside <TransitionChild>.
- Test transitions in dev mode where this assertion throws early.
When it happens
Trigger: Rendering <TransitionChild> whose child component swallows the `ref` (e.g., a custom wrapper with `inheritAttrs: false` or multiple root nodes, or returning null), or using `as="template"` around a component that doesn't use `useRenderStrategyFeatures`/forwards attrs, so `dom()` resolves to an empty comment node instead of an element.
Common situations: Wrapping Dialog/Popover/Menu panels in custom components; forgetting `v-bind="$attrs"` and `v-bind="attrs"` passthrough; single-file components with multiple root nodes (fragments) so Vue can't auto-attach the ref; conditional rendering that yields null during transition.
Related errors
- [Headless UI]: Cannot find ownerDocument for contextElement:
- A <TransitionChild /> is used but it is missing a parent <Tr
- A <Transition /> is used but it is missing a `:show="true |
- Did you forget to passthrough the `ref` to the actual DOM no
- Missing parent
AI-assisted analysis of tailwindlabs/headlessui@eea57cf46f (2026-08-28).
Data as JSON: /api/errors/5d3c532d1787fa16.
Report an issue: GitHub.