{"record":{"id":"2997b893497f6067","repo":"zed-industries/zed","slug":"dialog-owner-has-closed","errorCode":null,"errorMessage":"dialog owner has closed","messagePattern":"dialog owner has closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gpui_windows/src/dialog.rs","lineNumber":93,"sourceCode":"                .owner_closed\n                .as_ref()\n                .is_some_and(|closed| closed.load(Ordering::Acquire))\n    }\n}\n\n/// Native modal loops may synchronously message their owner, so the foreground\n/// thread must keep pumping messages rather than waiting for the dialog thread.\n/// Holding the owner's lock through native completion also allows window\n/// destruction to wait for the dialog without blocking the foreground thread.\npub(crate) fn show_dialog<T: Send + 'static>(\n    owner: Option<Rc<DialogOwner>>,\n    executor: &ForegroundExecutor,\n    dialog: impl FnOnce(HWND) -> Result<T> + Send + 'static,\n) -> oneshot::Receiver<Result<T>> {\n    let (mut sender, receiver) = oneshot::channel();\n    let cancellation = Cancellation::new(owner.as_deref());\n    if cancellation.is_requested() {\n        sender.send(Err(anyhow!(\"dialog owner has closed\"))).ok();\n        return receiver;\n    }\n    let hwnd = owner.as_ref().map(|owner| SafeHwnd::from(owner.hwnd));\n    executor\n        .spawn(async move {\n            // Let Windows manage enabling and activating the owner. Overlapping\n            // modal loops could otherwise re-enable it while another dialog is open.\n            let serialization = if let Some(owner) = owner.as_ref() {\n                match select(owner.serialization.lock(), sender.cancellation()).await {\n                    Either::Left((guard, _)) => Some(guard),\n                    Either::Right(((), _)) => return,\n                }\n            } else {\n                None\n            };\n            if sender.is_canceled() || cancellation.is_requested() {\n                return;\n            }","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/crates/gpui_windows/src/dialog.rs#L75-L111","documentation":"A sentinel validation error raised at the top of show_dialog: before spawning the dialog, Cancellation::is_requested() found the owner window's `closed` flag already set. It means the owning window was destroyed/closed before this dialog request could start, so the request is short-circuited and the receiver immediately gets this Err instead of launching a native dialog thread. There is no dialog to recover; the caller should treat the result as cancelled.","triggerScenarios":"Thrown at crates/gpui_windows/src/dialog.rs:93 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Treat the Err receiver the same as a cancelled dialog: skip awaiting the result or handle it as a no-op","Check the owner's closed state (DialogOwner::close/when_idle) before issuing dialog requests when the owner may be shutting down","Do not retry — a closed owner will never accept a new dialog; re-create the owner window first if a dialog is still needed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}