{"record":{"id":"96000da76f489930","repo":"tailwindlabs/headlessui","slug":"there-are-no-focusable-elements-inside-the-focust","errorCode":null,"errorMessage":"There are no focusable elements inside the <FocusTrap />","messagePattern":"There are no focusable elements inside the <FocusTrap />","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/@headlessui-vue/src/components/focus-trap/focus-trap.ts","lineNumber":331,"sourceCode":"\n          let activeElement = ownerDocument.value?.activeElement as HTMLElement\n\n          if (initialFocusElement) {\n            if (initialFocusElement === activeElement) {\n              previousActiveElement.value = activeElement\n              return // Initial focus ref is already the active element\n            }\n          } else if (containerElement!.contains(activeElement)) {\n            previousActiveElement.value = activeElement\n            return // Already focused within Dialog\n          }\n\n          // Try to focus the initialFocus ref\n          if (initialFocusElement) {\n            focusElement(initialFocusElement)\n          } else {\n            if (focusIn(containerElement!, Focus.First | Focus.NoScroll) === FocusResult.Error) {\n              console.warn('There are no focusable elements inside the <FocusTrap />')\n            }\n          }\n\n          previousActiveElement.value = ownerDocument.value?.activeElement as HTMLElement\n        })\n      },\n      { immediate: true, flush: 'post' }\n    )\n  })\n\n  return previousActiveElement\n}\n\nfunction useFocusLock(\n  {\n    ownerDocument,\n    container,\n    containers,","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/tailwindlabs/headlessui/blob/eea57cf46fd6767ed1059012f7073b88eb159fba/packages/@headlessui-vue/src/components/focus-trap/focus-trap.ts#L313-L349","documentation":"This warning is emitted by Headless UI Vue's <FocusTrap /> (used internally by <Dialog>) during initial focus when it cannot find ANY focusable element inside the trap container. The useInitialFocus hook tries the `initialFocus` ref first, then falls back to focusing the first focusable element via focusIn(container, Focus.First | Focus.NoScroll); when that returns FocusResult.Error the warning fires and the dialog opens with no element focused.","triggerScenarios":"Rendering a <Dialog> (or <FocusTrap>) whose content contains no focusable elements (no buttons, links, inputs, [tabindex] elements), while the initialFocus ref is unset or points to a detached/hidden element. Also occurs when the content is conditionally rendered empty on first paint, or when all children are `hidden`/`disabled`/`inert`.","commonSituations":"Dialogs that only display text plus a close button that renders conditionally; content loaded async so the panel is empty when the trap activates; custom initialFocus ref attached to an element removed from the DOM (e.g. v-if becomes false); using `static` or `unmount` props so the panel mounts before its children do.","solutions":["Add at least one focusable element inside the Dialog panel, such as a close <button> or the action buttons.","Point the initialFocus prop/ref at a real, mounted element: <Dialog :initialFocus=\"myRef\"> (or pass initialFocus to FocusTrap).","If content is async, delay rendering the Dialog until content exists, or use `unmount={false}`/keep a persistent focusable fallback element.","Ensure the intended target isn't disabled, hidden, or negatively tabbable (tabindex=\"-1\" alone is fine for programmatic focus, but display:none elements are not focusable)."],"exampleFix":"// before\n<Dialog @close=\"close\">\n  <DialogPanel>\n    <p>Just text, nothing focusable</p>\n  </DialogPanel>\n</Dialog>\n\n// after\n<Dialog @close=\"close\">\n  <DialogPanel>\n    <p>Just text</p>\n    <button @click=\"close\">Close</button>\n  </DialogPanel>\n</Dialog>\n\n<!-- or target a specific element -->\n<Dialog @close=\"close\" :initialFocus=\"cancelButtonRef\">\n  <DialogPanel>\n    <button ref=\"cancelButtonRef\" @click=\"close\">Cancel</button>\n  </DialogPanel>\n</Dialog>","handlingStrategy":"validation","validationCode":"// Vue: verify focusable content exists before opening\nimport { focusElement } from '@headlessui/vue'\nfunction hasFocusable(el: HTMLElement | null): boolean {\n  if (!el) return false\n  return el.querySelector(\n    'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])'\n  ) !== null\n}\nfunction openDialog(panel: HTMLElement | null, initialFocusEl?: HTMLElement) {\n  if (!initialFocusEl && !hasFocusable(panel)) {\n    console.warn('Dialog has no focusable content; adding fallback focus target')\n    panel?.setAttribute('tabindex', '-1')\n  }\n  isOpen.value = true\n}","typeGuard":"function isFocusable(el: Element | null): el is HTMLElement {\n  if (!el) return false\n  return (\n    !el.hasAttribute('disabled') &&\n    el.getAttribute('aria-hidden') !== 'true' &&\n    (el.matches('a[href],button,input,select,textarea,[tabindex]') ||\n      el.getAttribute('contenteditable') === 'true')\n  )\n}","tryCatchPattern":null,"preventionTips":["Always render at least one focusable action (e.g. Close button) inside the DialogPanel.","Pass :initial-focus to a ref on an element that is always mounted and enabled.","Delay opening the dialog until async content is rendered.","Run a keyboard-only smoke test (Tab) on every dialog you build."],"tags":["headlessui","vue","focus-trap","dialog","accessibility","keyboard-navigation"],"backgroundTag":"no-focusable-elements-in-container","analyzedSha":"eea57cf46fd6767ed1059012f7073b88eb159fba","analyzedAt":"2026-08-28T19:22:46.163Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}