zed-industries/zed · critical

Device lost: {err}

Error message

Device lost: {err}

What it means

gpui_windows runs a dedicated vsync thread that waits for vertical blank and also watches for DirectX device loss. When loss is detected it calls handle_gpu_device_lost to rebuild device, swapchain, and text-system state; if recovery returns an error the thread panics with 'Device lost'. Because the panic is on a background thread, it tears down the whole process rather than one window.

Source

Thrown at crates/gpui_windows/src/platform.rs:396

        let invalidate_devices = self.invalidate_devices.clone();

        std::thread::Builder::new()
            .name("VSyncProvider".to_owned())
            .spawn(move || {
                let vsync_provider = VSyncProvider::new();
                loop {
                    vsync_provider.wait_for_vsync();
                    if check_device_lost(&directx_device.device)
                        || invalidate_devices.fetch_and(false, Ordering::Acquire)
                    {
                        if let Err(err) = handle_gpu_device_lost(
                            &mut directx_device,
                            platform_window.as_raw(),
                            validation_number,
                            &all_windows,
                            &text_system,
                        ) {
                            panic!("Device lost: {err}");
                        }
                    }
                    let Some(all_windows) = all_windows.upgrade() else {
                        break;
                    };
                    for hwnd in all_windows.read().iter() {
                        unsafe {
                            let _ = RedrawWindow(Some(hwnd.as_raw()), None, None, RDW_INVALIDATE);
                        }
                    }
                }
            })
            .unwrap();
    }
}

fn translate_accelerator(msg: &MSG) -> Option<()> {
    if msg.message != WM_KEYDOWN && msg.message != WM_SYSKEYDOWN {

View on GitHub (pinned to 9d272b0363)

Solutions

  1. Update GPU drivers; check Event Viewer for the reset that started the recovery attempt
  2. Free VRAM and reduce concurrent GPU work so the recovery has resources to succeed
  3. Reboot to clear wedged driver state if the panic repeats on every launch
  4. Capture the err text from the panic plus surrounding events and report it upstream for the specific GPU/driver pair
Defensive patterns

Strategy: fallback

Try / catch

// the panic is on the vsync thread: catch_unwind there is not reachable from main,
// so record the failure and exit cleanly for an external supervisor to restart
std::panic::set_hook(Box::new(|info| {
    log::error!("panic on background thread: {info}");
    std::process::exit(101);
}));

Prevention

When it happens

Trigger: The vsync thread observes a lost device (check_device_lost or the invalidate-devices flag set by a device-removed notification) and handle_gpu_device_lost fails during re-enumeration, swapchain recreation, or dependent state rebuild on Windows.

Common situations: Same family as the message-loop variant: driver reset during heavy rendering, docking/undocking, driver upgrades, failing hardware. Slightly more likely when the loss happens between frames rather than during drawing, since this watcher thread is the one that notices it first.

Related errors


AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-08-20). Data as JSON: /api/errors/ec8a582012ecd405. Report an issue: GitHub.