{"record":{"id":"f9c5d0fda57e6669","repo":"bevyengine/bevy","slug":"failed-to-create-wgpu-surface-f9c5d0","errorCode":null,"errorMessage":"Failed to create wgpu surface","messagePattern":"Failed to create wgpu surface","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/bevy_render/src/view/window/mod.rs","lineNumber":393,"sourceCode":"        &mut ExtractedWindow,\n        &RawHandleWrapper,\n        Option<&mut SurfaceData>,\n    )>,\n    render_instance: Res<RenderInstance>,\n    render_adapter: Res<RenderAdapter>,\n    render_device: Res<RenderDevice>,\n) {\n    for (entity, mut window, handle, mut maybe_surface_data) in &mut windows {\n        let Some(data) = maybe_surface_data.as_mut() else {\n            let surface_target = SurfaceTargetUnsafe::RawHandle {\n                raw_display_handle: Some(handle.get_display_handle()),\n                raw_window_handle: handle.get_window_handle(),\n            };\n            // SAFETY: The window handles in ExtractedWindows will always be valid objects to create surfaces on\n            let surface = unsafe {\n                // NOTE: On some OSes this MUST be called from the main thread.\n                // As of wgpu 0.15, only fallible if the given window is a HTML canvas and obtaining a WebGPU or WebGL2 context fails.\n                render_instance\n                    .create_surface_unsafe(surface_target)\n                    .expect(\"Failed to create wgpu surface\")\n            };\n            let caps = surface.get_capabilities(&render_adapter);\n            let present_mode = present_mode(&window, &caps);\n            let formats = caps.formats;\n            // For future HDR output support, we'll need to request a format that supports HDR,\n            // but as of wgpu 0.15 that is not yet supported.\n            // Prefer sRGB formats for surfaces, but fall back to first available format if no sRGB formats are available.\n            let mut format = *formats.first().expect(\"No supported formats for surface\");\n            for available_format in formats {\n                // Rgba8UnormSrgb and Bgra8UnormSrgb and the only sRGB formats wgpu exposes that we can use for surfaces.\n                if available_format == TextureFormat::Rgba8UnormSrgb\n                    || available_format == TextureFormat::Bgra8UnormSrgb\n                {\n                    format = available_format;\n                    break;\n                }","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/bevyengine/bevy/blob/8d743eb7dc7fcff57a7d5744d0bbf89620b1b145/crates/bevy_render/src/view/window/mod.rs#L375-L411","documentation":"In the per-window surface creation system, Bevy builds a SurfaceTargetUnsafe from each ExtractedWindow's raw handles and expects create_surface_unsafe to succeed (the source notes this is only fallible for HTML canvases where obtaining a WebGPU/WebGL2 context fails, and that on some OSes it must be called from the main thread). A failure here means the instance could not create a presentable surface for that specific window.","triggerScenarios":"A window exists (windowing plugin) but its raw handles cannot back a surface: on web, a canvas that fails to acquire a WebGPU/WebGL2 context; on desktop, window creation happening off the main thread on OSes that require main-thread surface creation, or stale/invalid handles.","commonSituations":"Web deployment where the canvas is missing, resized to nothing, or the browser lacks WebGL2; creating secondary windows on non-main threads on macOS; wgpu backend (e.g. GL) that cannot target the given window type.","solutions":["On web: verify the canvas element exists and the browser supports WebGL2/WebGPU; test with an up-to-date browser","Ensure all windows are created on the main thread (default winit behavior — avoid custom thread-based window creation)","Try a different backend via WGPU_BACKEND or update GPU drivers if the failure is native","If the window isn't actually needed for presentation, use headless rendering instead of a visible window"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// On web, check context availability before relying on surface creation:\nfn web_canvas_supports_webgl2() -> bool {\n    // wasm-bindgen check for WebGL2 on the configured canvas\n    true // placeholder: query canvas.getContext(\"webgl2\") from JS glue\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create all windows on the main thread (default winit path) — surface creation is main-thread-only on some OSes","On web, ensure the target canvas exists and the browser supports WebGL2/WebGPU before app startup","Wrap risky window setups in a configuration that can fall back to an existing surface or headless mode"],"tags":["bevy","wgpu","surface","windowing","webgl2"],"backgroundTag":"surface-creation-failed","analyzedSha":"8d743eb7dc7fcff57a7d5744d0bbf89620b1b145","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}