tailwindlabs/headlessui · error · Error
Missing Focus.First, Focus.Previous, Focus.Next or Focus.Las
Error message
Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last
What it means
`focusIn(container, focus)` from Headless UI's focus-management utility computes a traversal direction from the `focus` bitmask. It requires one of the directional flags Focus.First, Focus.Previous, Focus.Next, or Focus.Last; if none is set, the direction computation throws immediately.
Source
Thrown at packages/@headlessui-vue/src/utils/focus-management.ts:222
: container?.ownerDocument) ?? document
let elements = Array.isArray(container)
? sorted
? sortByDomNode(container)
: container
: getFocusableElements(container)
if (skipElements.length > 0 && elements.length > 1) {
elements = elements.filter((x) => !skipElements.includes(x))
}
relativeTo = relativeTo ?? (ownerDocument.activeElement as HTMLElement)
let direction = (() => {
if (focus & (Focus.First | Focus.Next)) return Direction.Next
if (focus & (Focus.Previous | Focus.Last)) return Direction.Previous
throw new Error('Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last')
})()
let startIndex = (() => {
if (focus & Focus.First) return 0
if (focus & Focus.Previous) return Math.max(0, elements.indexOf(relativeTo)) - 1
if (focus & Focus.Next) return Math.max(0, elements.indexOf(relativeTo)) + 1
if (focus & Focus.Last) return elements.length - 1
throw new Error('Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last')
})()
let focusOptions = focus & Focus.NoScroll ? { preventScroll: true } : {}
let offset = 0
let total = elements.length
let next = undefined
do {
// Guard against infinite loopsView on GitHub (pinned to eea57cf46f)
Solutions
- Include exactly one direction flag: `focusIn(container, Focus.First | Focus.NoScroll)`.
- If computing flags dynamically, assert a direction bit is present before calling: `(flags & (Focus.First|Focus.Previous|Focus.Next|Focus.Last)) !== 0`.
- Prefer using the library's built-in components/keyboard handling rather than calling focusIn directly.
Example fix
// before focusIn(container, Focus.NoScroll) // after focusIn(container, Focus.First | Focus.NoScroll)
Defensive patterns
Strategy: validation
Validate before calling
const DIRECTION = Focus.First | Focus.Previous | Focus.Next | Focus.Last if ((flags & DIRECTION) === 0) flags |= Focus.First focusIn(container, flags)
Type guard
const hasDirection = (f: number) => (f & (Focus.First | Focus.Previous | Focus.Next | Focus.Last)) !== 0
Prevention
- Always OR a direction flag with modifiers.
- Import Focus from the package itself to avoid undefined flags.
- Prefer built-in components' keyboard handling over direct focusIn calls.
When it happens
Trigger: Calling `focusIn(el, Focus.NoScroll)` or `focusIn(el, 0)` (only modifier flags set); passing a custom numeric value that doesn't include a direction bit; building the flags dynamically and accidentally passing only Focus.WrapAround/NoScroll.
Common situations: Custom keyboard handlers in menus/dialogs that pass only modifier flags; refactor typos where the direction constant is dropped; calling the internal `focusIn`/`focusFrom` API directly instead of higher-level components.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Missing Focus.First, Focus.Previous, Focus.Next or Focus.Las
- Passing props on "Fragment"! The current component <${name}
- Missing parent
- You forgot to provide an `open` prop to the `Dialog`.
- You provided an `open` prop to the `Dialog`, but the value i
AI-assisted analysis of tailwindlabs/headlessui@eea57cf46f (2026-08-28).
Data as JSON: /api/errors/129755f3406c5548.
Report an issue: GitHub.