zed-industries/zed · info
dialog cancelled
Error message
dialog cancelled
What it means
show_dialog runs the platform dialog on a background thread and can be cancelled (e.g. the window was closed or a timeout fired via CancellationTimer). Before and after invoking the dialog callback, the thread checks the cancellation token; if cancellation was requested it aborts with this anyhow error instead of returning dialog results. It is a deliberate cooperative-cancellation signal, not a bug.
Solutions
- Treat the error as benign cancellation: filter it out where dialog results are consumed instead of logging it as a failure.
- Avoid closing/dropping the window that owns the dialog request until the dialog future resolves, or keep a handle so cancellation is intentional.
- If it fires frequently at startup, investigate slow Apartment::new / thread startup that widens the cancellation race window.
- Check whether CancellationTimer's timeout is too aggressive for the environment and raise it if dialogs legitimately take long.
Example fix
// before
if let Err(e) = show_dialog(...).await {
log::error!("dialog failed: {e}");
}
// after
if let Err(e) = show_dialog(...).await {
if !e.to_string().contains("dialog cancelled") {
log::error!("dialog failed: {e}");
}
} Defensive patterns
Strategy: try-catch
Try / catch
match show_dialog(cx).await {
Ok(result) => handle(result),
Err(e) if e.to_string().contains("dialog cancelled") => {}, // benign
Err(e) => log::error!("dialog failed: {e:#}"),
} Prevention
- Keep the owning window alive until the dialog future resolves
- Treat 'dialog cancelled' as a normal control-flow outcome, not a failure
- Avoid spawning dialogs during app shutdown sequences
When it happens
Trigger: Calling show_dialog and then closing the window / dropping the requester before the background thread reaches the dialog callback (pre-dialog check at line 122), or the CancellationTimer expiring while the dialog is being spawned.
Common situations: Rapidly closing a window while a file-picker or message box is still opening; slow COM apartment startup on a busy system; teardown races during app shutdown where the dialog request outlives its owner.
Related errors
- Autoupdate failed, nothing to rollback
- Autoupdate failed, rollback successful
- Buffer edited while formatting. Aborting
- Delete operations cannot be rolled back, file
- Device lost
AI-assisted analysis of zed-industries/zed@916fc2b8cb (2026-09-19).
Data as JSON: /api/errors/b8ecd7f765fea339.
Report an issue: GitHub.
Appendix: source
Thrown at crates/gpui_windows/src/dialog.rs:122
Either::Right(((), _)) => return,
}
} else {
None
};
if sender.is_canceled() || cancellation.is_requested() {
return;
}
let (result_sender, mut result_receiver) = oneshot::channel();
let thread = std::thread::Builder::new()
.name("windows-native-dialog".into())
.spawn({
let cancellation = cancellation.clone();
move || {
let result = (|| {
let _apartment = Apartment::new()?;
let _timer = CancellationTimer::new(cancellation.clone())?;
if cancellation.is_requested() {
return Err(anyhow!("dialog cancelled"));
}
let result = dialog(hwnd.map(|hwnd| hwnd.as_raw()).unwrap_or_default());
if cancellation.is_requested() {
return Err(anyhow!("dialog cancelled"));
}
result
})();
result_sender.send(result).ok();
}
});
if let Err(error) = thread {
drop(serialization);
sender.send(Err(error.into())).ok();
return;
}
let result = match select(&mut result_receiver, sender.cancellation()).await {
Either::Left((result, _)) => result,
Either::Right(((), _)) => {View on GitHub (pinned to 916fc2b8cb)