{"record":{"id":"99a8b598958b5559","repo":"emilk/egui","slug":"install-surface-called-before-render-state-initial","errorCode":null,"errorMessage":"install_surface called before render_state initialization","messagePattern":"install_surface called before render_state initialization","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/egui-wgpu/src/winit.rs","lineNumber":262,"sourceCode":"\n    /// Inserts a freshly created surface into [`Self::surfaces`] and configures it.\n    ///\n    /// Render state must already be initialised before calling this.\n    // NOTE: The same assumption is already required by `resize_and_generate_depth_texture_view_and_msaa_view`.\n    fn install_surface(\n        &mut self,\n        surface: wgpu::Surface<'static>,\n        viewport_id: ViewportId,\n        width: u32,\n        height: u32,\n        resizing: bool,\n    ) {\n        let alpha_mode = {\n            // Panic: We use the same failure mode as `resize_and_generate_depth_texture_view_and_msaa_view`\n            let render_state = self\n                .render_state\n                .as_ref()\n                .expect(\"install_surface called before render_state initialization\");\n            if self.support_transparent_backbuffer {\n                let supported_alpha_modes =\n                    surface.get_capabilities(&render_state.adapter).alpha_modes;\n                // Prefer pre multiplied over post multiplied!\n                if supported_alpha_modes.contains(&wgpu::CompositeAlphaMode::PreMultiplied) {\n                    wgpu::CompositeAlphaMode::PreMultiplied\n                } else if supported_alpha_modes.contains(&wgpu::CompositeAlphaMode::PostMultiplied)\n                {\n                    wgpu::CompositeAlphaMode::PostMultiplied\n                } else {\n                    log::warn!(\n                        \"Transparent window was requested, but the active wgpu surface does not support a `CompositeAlphaMode` with transparency.\"\n                    );\n                    wgpu::CompositeAlphaMode::Auto\n                }\n            } else {\n                wgpu::CompositeAlphaMode::Auto\n            }","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/emilk/egui/blob/8fb03c9ae9a6bf1ffa602dfba51ed575f2655975/crates/egui-wgpu/src/winit.rs#L244-L280","documentation":"install_surface asserts self.render_state.is_some() before configuring a newly created surface, panicking with \"install_surface called before render_state initialization\" if the renderer's wgpu render state has not been set up yet. Render state (instance, adapter, device, queue) is normally created once up front; installing or recreating a surface before that initialization completes leaves the code without an adapter/device to query capabilities and configure against, so it panics.","triggerScenarios":"Calling install_surface indirectly via recreate_surface or add_surface before RenderState has been created (e.g. attempting to add a viewport/surface during startup before egui_wgpu::Renderer / RenderState::new finished, or after render_state was taken/failed). Also triggered by calling these internals directly in custom viewport code that runs before set_up / renderer init.","commonSituations":"Custom multi-viewport code installing surfaces for secondary windows during app construction, before the first frame initialized the painter; async RenderState creation still pending when a window-creation callback fires; a failed/skipped render-state initialization (e.g. no compatible adapter) followed by surface teardown/recreate calls.","solutions":["Ensure the egui_wgpu painter/renderer is fully initialized (RenderState created) before calling recreate_surface/add_surface/install_surface — typically create the painter, then install surfaces.","Defer surface installation until after first-frame initialization: create secondary-window surfaces in a later event-loop iteration once render_state exists.","If render-state creation can fail, handle that case explicitly and skip surface recreation instead of proceeding with a None render_state.","When writing custom viewport code, check painter.render_state before touching surfaces and route surface setup through the public painter APIs."],"exampleFix":"// before: installing a surface before render state exists\nlet painter = egui_wgpu::ScreenDescriptorlessPainter::new(...); // render_state not yet created\npainter.add_surface(surface, viewport_id, 0, 0, false); // panics\n// after: initialize render state first\nlet painter = egui_wgpu::Painter::new(config);\npainter.set_window(viewport_id, Some(window.clone()))?; // triggers RenderState init\n// only then:\npainter.add_surface(surface, viewport_id, width, height, transparent);","handlingStrategy":"validation","validationCode":"// Rust: only install surfaces once render state is initialized\nif painter.render_state().is_none() {\n    painter.set_window(viewport_id, Some(window.clone()))?; // triggers init\n}","typeGuard":"fn render_state_ready(painter: &egui_wgpu::Painter) -> bool {\n    painter.render_state().is_some()\n}","tryCatchPattern":null,"preventionTips":["Complete painter/RenderState initialization before add_surface/recreate_surface calls.","Create secondary-window surfaces in a later event-loop iteration, not during app construction.","Handle failed render-state init explicitly (e.g. no compatible adapter) instead of letting surface setup proceed."],"tags":["wgpu","winit","initialization-order","panic"],"backgroundTag":"invalid-state-transition","analyzedSha":"8fb03c9ae9a6bf1ffa602dfba51ed575f2655975","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}