iced-rs/iced · critical
Get window canvas
Error message
Get window canvas
What it means
On wasm32 targets, the winit runtime calls window.canvas() (WindowExtWebSys) and expects it to return Some. winit's web backend returns None when the browser window has no valid canvas element to associate with the WebGL/WebGPU context (e.g. the Window was created from a closed/invalid context or the DOM state is unexpected).
Source
Thrown at winit/src/lib.rs:348
let mut window_attributes = window_attributes;
#[cfg(target_os = "macos")]
let position = window_attributes.position.take();
let window = event_loop
.create_window(window_attributes)
.expect("Create window");
#[cfg(target_os = "macos")]
if let Some(position) = position {
window.set_outer_position(position);
}
#[cfg(target_arch = "wasm32")]
{
use winit::platform::web::WindowExtWebSys;
let canvas = window.canvas().expect("Get window canvas");
let _ = canvas.set_attribute(
"style",
"display: block; width: 100%; height: 100%",
);
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let body = document.body().unwrap();
let target = target.and_then(|target| {
body.query_selector(&format!("#{target}"))
.ok()
.unwrap_or(None)
});
match target {
Some(node) => {View on GitHub (pinned to d146509d89)
Solutions
- Ensure the wasm is started on the main thread with DOM access (no web worker entry point).
- Check the index.html template matches the winit/iced version's expected structure (a <canvas> or body element must exist).
- Verify document.body exists at startup time - wait for DOMContentLoaded before running the app.
- Align iced/winit/web-sys versions; the web backend's canvas handling changed across releases.
- Test in a plain browser page first to rule out webview/iframe quirks.
Example fix
// before (html) <div id="app"></div> // after (html) <body><canvas id="iced-canvas"></canvas></body>
Defensive patterns
Strategy: validation
Validate before calling
// ensure a canvas exists before starting the wasm app
if (!document.querySelector("canvas")) {
const c = document.createElement("canvas");
document.body.appendChild(c);
} Type guard
function hasCanvas(): boolean {
return typeof document !== "undefined"
&& document.body !== null
&& document.querySelector("canvas") !== null;
} Prevention
- Start the wasm app on the main thread with DOM access only.
- Keep the index.html template matching your iced/winit web backend version.
- Wait for DOMContentLoaded/load before mounting.
- Test outside webviews/iframes first to isolate environment quirks.
When it happens
Trigger: Running an iced wasm app where event_loop.create_window succeeds but window.canvas() returns None - typically when the HTML page lacks the expected canvas setup or the window was obtained in a worker/off-screen context.
Common situations: Serving the app from an HTML template missing the <canvas> or incompatible winit/iced web entry point; opening the page inside an iframe/webview with unusual document.body state; running the wasm in a web worker without DOM access.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of iced-rs/iced@d146509d89 (2026-09-11).
Data as JSON: /api/errors/9f5c62f0e596becb.
Report an issue: GitHub.