{"record":{"id":"17cc051b78b513ce","repo":"tailwindlabs/headlessui","slug":"missing-focus-first-focus-previous-focus-next-or","errorCode":null,"errorMessage":"Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last","messagePattern":"Missing Focus\\.First, Focus\\.Previous, Focus\\.Next or Focus\\.Last","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@headlessui-react/src/utils/focus-management.ts","lineNumber":280,"sourceCode":"  if (skipElements.length > 0 && elements.length > 1) {\n    elements = elements.filter(\n      (element) =>\n        !skipElements.some(\n          (skipElement) =>\n            skipElement != null && 'current' in skipElement\n              ? skipElement?.current === element // Handle MutableRefObject\n              : skipElement === element // Handle HTMLElement directly\n        )\n    )\n  }\n\n  relativeTo = relativeTo ?? (root?.activeElement as HTMLElement)\n\n  let direction = (() => {\n    if (focus & (Focus.First | Focus.Next)) return Direction.Next\n    if (focus & (Focus.Previous | Focus.Last)) return Direction.Previous\n\n    throw new Error('Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last')\n  })()\n\n  let startIndex = (() => {\n    if (focus & Focus.First) return 0\n    if (focus & Focus.Previous) return Math.max(0, elements.indexOf(relativeTo)) - 1\n    if (focus & Focus.Next) return Math.max(0, elements.indexOf(relativeTo)) + 1\n    if (focus & Focus.Last) return elements.length - 1\n\n    throw new Error('Missing Focus.First, Focus.Previous, Focus.Next or Focus.Last')\n  })()\n\n  let focusOptions = focus & Focus.NoScroll ? { preventScroll: true } : {}\n\n  let offset = 0\n  let total = elements.length\n  let next = undefined\n  do {\n    // Guard against infinite loops","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/tailwindlabs/headlessui/blob/eea57cf46fd6767ed1059012f7073b88eb159fba/packages/@headlessui-react/src/utils/focus-management.ts#L262-L298","documentation":"Thrown by Headless UI's internal focusIn() helper when the focus flag passed to it does not include any directional bit (Focus.First, Focus.Previous, Focus.Next, or Focus.Last). focusIn() computes a movement direction from these flags; without one, there is no direction to move and the API contract is violated. This almost always means a caller passed 0, an undefined value, or only modifier flags like Focus.NoScroll.","triggerScenarios":"Calling focusIn(elements, Focus.NoScroll) with no directional bit; passing 0 or an undefined `focus` argument; building a custom flag mask that omits First/Previous/Next/Last; internal components invoked with a corrupted Focus enum (e.g. tree-shaking or duplicate @headlessui versions mangling the enum values).","commonSituations":"Custom widgets copying Headless UI internals; passing a focus option read from user input/config that defaults to 0; mixing two different @headlessui-react versions in a monorepo so the Focus enum values from one copy don't match the other's.","solutions":["Pass a directional flag: use focusIn(elements, Focus.First) or combine with modifiers, e.g. focusIn(elements, Focus.First | Focus.NoScroll).","If the flag comes from a variable, verify it is always one of Focus.First/Previous/Next/Last (optionally OR-ed with Focus.NoScroll) and never 0/undefined.","Check for duplicate @headlessui-react installs (npm ls @headlessui/react) and dedupe so enum values are consistent."],"exampleFix":"// before\nfocusIn(elements, Focus.NoScroll) // no direction bit -> throws\n\n// after\nfocusIn(elements, Focus.First | Focus.NoScroll)","handlingStrategy":"validation","validationCode":"import { Focus } from '@headlessui/react'\n\nconst DIRECTION = Focus.First | Focus.Previous | Focus.Next | Focus.Last\nfunction isValidFocusFlag(focus: number): boolean {\n  return (focus & DIRECTION) !== 0\n}\n\n// before calling:\nif (!isValidFocusFlag(flags)) flags = Focus.First\nfocusIn(elements, flags)","typeGuard":"const hasDirection = (f: number): f is number => (f & (Focus.First | Focus.Previous | Focus.Next | Focus.Last)) !== 0","tryCatchPattern":"try { focusIn(elements, flags) } catch (e) { if (e instanceof Error && e.message.includes('Missing Focus.')) { focusIn(elements, Focus.First) } else throw e }","preventionTips":["Always type focus parameters as Focus (the enum), not number, so invalid masks are caught at compile time.","Centralize flag construction in one helper that asserts a direction bit is present.","Keep a single copy of @headlessui-react in the dependency tree to avoid enum drift."],"tags":["headlessui","focus-management","invalid-argument","accessibility"],"backgroundTag":"invalid-enum-flag-argument","analyzedSha":"eea57cf46fd6767ed1059012f7073b88eb159fba","analyzedAt":"2026-08-28T19:22:46.163Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}