emilk/egui · error
winit window doesn't exist
Error message
winit window doesn't exist
What it means
`GlowIntegration::window` calls `window_opt(viewport_id)` and unwraps the result with `expect("winit window doesn't exist")`. A viewport entry exists in `self.viewports`, but its `window: Option<Arc<Window>>` is `None`. The library assumes any viewport present in the map (other than transient states) has an associated winit window; `None` indicates the window was closed/destroyed without removing the viewport entry, or the viewport is still being initialized.
Source
Thrown at crates/eframe/src/native/glow_integration.rs:1417
} else {
log::debug!("context is already not current??? could be duplicate suspend event");
}
Ok(())
}
fn viewport(&self, viewport_id: ViewportId) -> &Viewport {
self.viewports
.get(&viewport_id)
.expect("viewport doesn't exist")
}
fn window_opt(&self, viewport_id: ViewportId) -> Option<Arc<Window>> {
self.viewport(viewport_id).window.clone()
}
fn window(&self, viewport_id: ViewportId) -> Arc<Window> {
self.window_opt(viewport_id)
.expect("winit window doesn't exist")
}
fn resize(&mut self, viewport_id: ViewportId, physical_size: winit::dpi::PhysicalSize<u32>) {
let width_px = NonZeroU32::new(physical_size.width).unwrap_or(NonZeroU32::MIN);
let height_px = NonZeroU32::new(physical_size.height).unwrap_or(NonZeroU32::MIN);
if let Some(viewport) = self.viewports.get(&viewport_id)
&& let Some(gl_surface) = &viewport.gl_surface
{
change_gl_context(
&mut self.current_gl_context,
&mut self.not_current_gl_context,
gl_surface,
);
gl_surface.resize(
self.current_gl_context
.as_ref()
.expect("failed to get current context to resize surface"),View on GitHub (pinned to 441971a776)
Solutions
- Prefer `window_opt` in your own integration code and handle the `None` case instead of the panicking `window` API.
- Ensure viewport removal happens in the same frame the window is destroyed so `viewports` never holds entries with `None` windows.
- Guard event handling against events for closed viewports (check the id before calling `window`).
- If reproducible, file an eframe issue with the event sequence; as a workaround disable viewports in `NativeOptions`.
Example fix
// before
let window = integration.window(viewport_id);
// after
if let Some(window) = integration.window_opt(viewport_id) {
// use window
} else {
log::warn!("window for {:?} already closed", viewport_id);
} Defensive patterns
Strategy: validation
Validate before calling
// Prefer the fallible accessor before touching the window
if let Some(window) = runner.window_opt(viewport_id) {
use_window(&window);
} else {
eprintln!("viewport {:?} has no window; skipping", viewport_id);
} Type guard
fn live_window(v: &Viewport) -> Option<Arc<Window>> { v.window.clone() } Prevention
- Use window_opt instead of window in custom integration code
- Destroy the viewport record in the same frame its window is closed
- Ignore events arriving for ids you have already closed
When it happens
Trigger: Calling `window(viewport_id)` for a viewport whose `window` field is `None` — typically during teardown, when the window was destroyed (e.g. `ViewportCommand::Close` processed) but the viewport record lingers, or when the id refers to a viewport mid-creation.
Common situations: Handling a winit event (resize, redraw, user-close) for a window that was just destroyed; deferred viewport code running after the parent closed the child window; race between close handling and the event loop delivering one more event for the dead id.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- viewport doesn't exist
- Window did not show
- Window was collapsed
- Harness::ui_id is only available for harnesses built with a
- Single-use AppCreator has unexpectedly already been taken
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/31764e7be434b7e6.
Report an issue: GitHub.