{"record":{"id":"5a69b17e73997e90","repo":"zed-industries/zed","slug":"too-many-consecutive-gpu-errors-last-error-erro","errorCode":null,"errorMessage":"Too many consecutive GPU errors. Last error: {error}","messagePattern":"Too many consecutive GPU errors\\. Last error: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/gpui_wgpu/src/wgpu_renderer.rs","lineNumber":1295,"sourceCode":"        // Bail out early if the surface has been unconfigured (e.g. during\n        // Android background/rotation transitions).  Attempting to acquire\n        // a texture from an unconfigured surface can block indefinitely on\n        // some drivers (Adreno).\n        if !self.surface_configured {\n            return false;\n        }\n\n        let last_error = self.last_error.lock().unwrap().take();\n        if let Some(error) = last_error {\n            self.failed_frame_count += 1;\n            log::error!(\n                \"GPU error during frame (failure {} of 10): {error}\",\n                self.failed_frame_count\n            );\n\n            // TBD. Does retrying more actually help?\n            if self.failed_frame_count > 10 {\n                panic!(\"Too many consecutive GPU errors. Last error: {error}\");\n            } else if self.failed_frame_count > 5 {\n                if let Some(res) = self.resources.as_mut() {\n                    res.invalidate_intermediate_textures();\n                }\n                self.atlas.clear();\n                self.needs_redraw = true;\n                self.failed_frame_count = 0;\n                return false;\n            }\n        } else {\n            self.failed_frame_count = 0;\n        }\n\n        self.atlas.before_frame();\n\n        let frame = match self.resources().surface.get_current_texture() {\n            wgpu::CurrentSurfaceTexture::Success(frame) => frame,\n            wgpu::CurrentSurfaceTexture::Suboptimal(frame) => {","sourceCodeStart":1277,"sourceCodeEnd":1313,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/gpui_wgpu/src/wgpu_renderer.rs#L1277-L1313","documentation":"The wgpu backend of GPUI checks after each frame whether the GPU reported an error. A few consecutive failures trigger recovery (after 5 failures intermediate textures and the atlas are invalidated and a redraw is forced), but once more than 10 consecutive failing frames accumulate the renderer gives up and panics with the last error. It is a circuit breaker against a persistently broken device or render loop, not against a single transient glitch.","triggerScenarios":"The wgpu device keeps erroring every frame: driver crash or reset, out-of-video-memory, a broken backend for the installed driver (e.g. misbehaving Vulkan stack), or genuinely invalid pipeline/render state in a custom renderer built on gpui_wgpu. Recovery at failure 5 did not help and errors continued past 10.","commonSituations":"Outdated or buggy GPU drivers, especially Linux Vulkan stacks; VMs and remote-desktop sessions with weak GPU support; apps leaking textures until VRAM runs out; browser/WebGPU differences when running the wasm build.","solutions":["Update the GPU driver and, on Linux, try a different backend via the WGPU_BACKEND environment variable (e.g. WGPU_BACKEND=gl or vulkan) to bypass a broken driver path","Free GPU memory: close other GPU-heavy apps and check your own renderer for texture/atlas leaks","Run with RUST_LOG=wgpu=debug to capture the actual wgpu error string that follows 'Last error:' and fix that specific error","If it is hardware/driver specific, report upstream with the error text, adapter info, and driver version"],"exampleFix":"# before: default backend picks a broken driver path, panics after ~10 frames\nWGPU_BACKEND=auto ./your_app\n\n# after: force a stable backend and capture the underlying wgpu error\nWGPU_BACKEND=gl RUST_LOG=wgpu=debug ./your_app","handlingStrategy":"fallback","validationCode":"// if you own device setup, reject known-bad adapters before creating the renderer\nlet instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());\nif let Some(adapter) = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await {\n    let info = adapter.get_info();\n    if info.backend == wgpu::Backend::Gl && requires_modern_gpu {\n        // surface a clear error instead of letting the frame circuit breaker panic later\n        return Err(anyhow!(\"only OpenGL adapter available; GPU support insufficient\"));\n    }\n}","typeGuard":null,"tryCatchPattern":"// supervisor: let the renderer circuit-break without taking the process down silently\nlet outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| run_ui_loop()));\nif outcome.is_err() {\n    log::error!(\"renderer panicked after repeated GPU errors; restarting\");\n    recreate_renderer_or_exit_gracefully();\n}","preventionTips":["Keep GPU drivers current, especially on Linux where backend quality varies","Watch VRAM usage in your renderer; release textures and atlas entries you no longer use","Run with RUST_LOG=wgpu=debug in QA so the underlying 'Last error' string is always captured","Expose a backend override (e.g. WGPU_BACKEND) so users on broken drivers can switch paths"],"tags":["gpui","wgpu","gpu","driver","panic","out-of-memory"],"backgroundTag":"gpu-device-lost","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}