{"record":{"id":"fb1d4a32620bacf4","repo":"iced-rs/iced","slug":"non-zero-width","errorCode":null,"errorMessage":"Non-zero width","messagePattern":"Non-zero width","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tiny_skia/src/window/compositor.rs","lineNumber":82,"sourceCode":"        let mut surface = Surface {\n            window,\n            clip_mask: tiny_skia::Mask::new(1, 1).expect(\"Create clip mask\"),\n            frames: VecDeque::new(),\n            max_age: 0,\n        };\n\n        if width > 0 && height > 0 {\n            self.configure_surface(&mut surface, width, height);\n        }\n\n        surface\n    }\n\n    fn configure_surface(&mut self, surface: &mut Self::Surface, width: u32, height: u32) {\n        surface\n            .window\n            .resize(\n                NonZeroU32::new(width).expect(\"Non-zero width\"),\n                NonZeroU32::new(height).expect(\"Non-zero height\"),\n            )\n            .expect(\"Resize surface\");\n\n        surface.clip_mask = tiny_skia::Mask::new(width, height).expect(\"Create clip mask\");\n        surface.frames.clear();\n    }\n\n    fn information(&self) -> Information {\n        Information {\n            adapter: String::from(\"CPU\"),\n            backend: String::from(\"tiny-skia\"),\n        }\n    }\n\n    fn present(\n        &mut self,\n        renderer: &mut Self::Renderer,","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/iced-rs/iced/blob/3de451447bd28217bb535632867550908e29d5d0/tiny_skia/src/window/compositor.rs#L64-L100","documentation":"configure_surface resizes the softbuffer surface, whose API requires NonZeroU32 dimensions; iced converts with NonZeroU32::new(width).expect(\"Non-zero width\"), which panics when width == 0. Inside create_surface the call is guarded by width > 0 && height > 0 (compositor.rs:71), and iced_winit skips configuration when the physical size is zero (winit/src/lib.rs:759-761), so the panic is only reachable when the Compositor trait is driven directly with a zero width.","triggerScenarios":"Embedding iced_tiny_skia's Compositor directly and calling configure_surface(&mut surface, 0, height); a custom winit event loop that forwards a minimized window's 0x0 resize straight to configure_surface without the guard the stock runtime has; reading window.inner_size() before the first layout completes.","commonSituations":"Custom shells and runtime integrations built on iced_tiny_skia/iced_winit primitives; test harnesses driving the compositor headlessly; platforms that report 0x0 while a window is minimized or hidden.","solutions":["Guard the call exactly like the stock runtime: skip configure_surface when width or height is 0","Clamp dimensions to at least 1 pixel if a resize must always be applied","If you maintain the integration, map zero sizes to a no-op instead of letting the expect fire"],"exampleFix":"// before\ncompositor.configure_surface(&mut surface, size.width, size.height);\n\n// after\nif size.width > 0 && size.height > 0 {\n    compositor.configure_surface(&mut surface, size.width, size.height);\n}","handlingStrategy":"validation","validationCode":"// Before configuring a surface in a custom runtime:\nfn is_configurable(size: (u32, u32)) -> bool {\n    size.0 > 0 && size.1 > 0\n}\n\nif is_configurable((physical.width, physical.height)) {\n    compositor.configure_surface(&mut surface, physical.width, physical.height);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mirror iced_winit's guard: it skips configuration whenever physical width or height is 0 (winit/src/lib.rs:759)","Never forward raw inner_size() values from minimized windows to the compositor"],"tags":["softbuffer","tiny-skia","nonzero","window-resize","rust"],"backgroundTag":"zero-size-window-dimensions","analyzedSha":"3de451447bd28217bb535632867550908e29d5d0","analyzedAt":"2026-08-17T10:40:26.997Z","contentChangedAt":"2026-08-17T10:40:26.997Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}