{"record":{"id":"054b9f507bb98258","repo":"tailwindlabs/headlessui","slug":"you-have-to-provide-an-open-and-an-onclose-pro","errorCode":null,"errorMessage":"You have to provide an `open` and an `onClose` prop to the `Dialog` component.","messagePattern":"You have to provide an `open` and an `onClose` prop to the `Dialog` component\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@headlessui-react/src/components/dialog/dialog.tsx","lineNumber":387,"sourceCode":"    autoFocus?: boolean\n    transition?: boolean\n    __demoMode?: boolean\n  }\n>\n\nfunction DialogFn<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG>(\n  props: DialogProps<TTag>,\n  ref: Ref<HTMLElement>\n) {\n  let { transition = false, open, ...rest } = props\n\n  // Validations\n  let usesOpenClosedState = useOpenClosed()\n  let hasOpen = props.hasOwnProperty('open') || usesOpenClosedState !== null\n  let hasOnClose = props.hasOwnProperty('onClose')\n\n  if (!hasOpen && !hasOnClose) {\n    throw new Error(\n      `You have to provide an \\`open\\` and an \\`onClose\\` prop to the \\`Dialog\\` component.`\n    )\n  }\n\n  if (!hasOpen) {\n    throw new Error(\n      `You provided an \\`onClose\\` prop to the \\`Dialog\\`, but forgot an \\`open\\` prop.`\n    )\n  }\n\n  if (!hasOnClose) {\n    throw new Error(\n      `You provided an \\`open\\` prop to the \\`Dialog\\`, but forgot an \\`onClose\\` prop.`\n    )\n  }\n\n  if (!usesOpenClosedState && typeof props.open !== 'boolean') {\n    throw new Error(","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/tailwindlabs/headlessui/blob/eea57cf46fd6767ed1059012f7073b88eb159fba/packages/@headlessui-react/src/components/dialog/dialog.tsx#L369-L405","documentation":"Headless UI React's Dialog is designed for controlled usage: it must know when it's open (`open`) and how to close (`onClose`). During render it checks `props.hasOwnProperty('open')` (or that an OpenClosed context provider supplies state) and `props.hasOwnProperty('onClose')`; if neither is present it throws this combined error.","triggerScenarios":"`<Dialog>...</Dialog>` with neither an `open` prop nor an `onClose` handler; attempting uncontrolled usage, which Dialog does not support.","commonSituations":"Copy-pasting a Dialog shell from examples and forgetting the props; assuming Dialog has an uncontrolled `open` default like native <dialog>; using Dialog with a state manager that passes props conditionally so both end up omitted.","solutions":["Control the Dialog: `<Dialog open={isOpen} onClose={close}>...`.","Or wrap the Dialog in an OpenClosedProvider-based component (e.g., DialogPanel inside a parent transition) if using the nested APIs.","If you wanted an uncontrolled dialog, track the boolean yourself in useState and pass it explicitly."],"exampleFix":"// before\n<Dialog>...</Dialog>\n\n// after\nconst [isOpen, setIsOpen] = useState(false)\n<Dialog open={isOpen} onClose={() => setIsOpen(false)}>...</Dialog>","handlingStrategy":"type-guard","validationCode":"const [isOpen, setIsOpen] = useState(false)\n// <Dialog open={isOpen} onClose={() => setIsOpen(false)}>","typeGuard":"const hasDialogProps = (p: { open?: unknown; onClose?: unknown }) => 'open' in p && 'onClose' in p","tryCatchPattern":null,"preventionTips":["Always set up open/onClose as a pair when scaffolding a Dialog.","Remember Dialog is controlled-only; there is no defaultOpen."],"tags":["headlessui","react","dialog","controlled-component","missing-prop"],"backgroundTag":"missing-required-prop","analyzedSha":"eea57cf46fd6767ed1059012f7073b88eb159fba","analyzedAt":"2026-08-28T19:22:46.163Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}