{"record":{"id":"fb83f4be19983485","repo":"tailwindlabs/headlessui","slug":"you-provided-an-onclose-prop-to-the-dialog-bu","errorCode":null,"errorMessage":"You provided an `onClose` prop to the `Dialog`, but forgot an `open` prop.","messagePattern":"You provided an `onClose` prop to the `Dialog`, but forgot an `open` prop\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@headlessui-react/src/components/dialog/dialog.tsx","lineNumber":393,"sourceCode":"function 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(\n      `You provided an \\`open\\` prop to the \\`Dialog\\`, but the value is not a boolean. Received: ${props.open}`\n    )\n  }\n\n  if (typeof props.onClose !== 'function') {\n    throw new Error(","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/tailwindlabs/headlessui/blob/eea57cf46fd6767ed1059012f7073b88eb159fba/packages/@headlessui-react/src/components/dialog/dialog.tsx#L375-L411","documentation":"The Dialog render-time validation found an `onClose` prop but no `open` prop and no OpenClosed context state. Without `open`, the Dialog has no source of truth for visibility, so it refuses to render rather than silently never closing/opening.","triggerScenarios":"`<Dialog onClose={handleClose}>` without `open`; conditionally spreading props where the `open` key is dropped (`{...(cond ? {open} : {})}`); passing `defaultOpen` (which Dialog doesn't support) instead of `open`.","commonSituations":"Thinking `defaultOpen` or the presence of onClose implies controlled state; prop spreading bugs with conditional objects; migrating from Radix/native dialog APIs.","solutions":["Add the boolean: `<Dialog open={isOpen} onClose={handleClose}>`.","Check conditional spreads to ensure `open` is always included when `onClose` is.","Remove `defaultOpen`; Dialog is controlled-only."],"exampleFix":"// before\n<Dialog onClose={() => setOpen(false)}>...</Dialog>\n\n// after\n<Dialog open={open} onClose={() => setOpen(false)}>...</Dialog>","handlingStrategy":"type-guard","validationCode":"// Always pass open alongside onClose\n// <Dialog open={open ?? false} onClose={close}>","typeGuard":"const hasOpenProp = (p: object): boolean => 'open' in p || 'defaultOpen' in p && false /* unsupported */","tryCatchPattern":null,"preventionTips":["Pair open and onClose in one snippet/template you reuse.","Avoid conditional prop spreads that can drop `open`."],"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"}