slint-ui/slint · critical
winit backend: Specified DOM element
Error message
winit backend: Specified DOM element '{}' is not a HTML Canvas What it means
The wasm-interpreter found a DOM element with the requested id, but `dyn_into::<HtmlCanvasElement>()` failed, meaning the element exists yet is not a `<canvas>` (e.g. a `<div>`). The message text says 'winit backend' for historical reasons but is raised by the wasm-interpreter canvas lookup. Rendering requires an actual HTMLCanvasElement to pass to the winit WebSys backend.
Solutions
- Change the element with that id to a `<canvas>` element in the HTML
- Pass the id of the actual `<canvas>` element to init instead of a container div
- Ensure ids are unique so getElementById resolves the canvas, not another element
- Use `<canvas id="canvas">` boilerplate matching the default expected id
Example fix
// before <div id="canvas"></div> // after <canvas id="canvas"></canvas>
Defensive patterns
Strategy: type-guard
Validate before calling
const el = document.getElementById(canvasId);
if (!(el instanceof HTMLCanvasElement)) throw new Error(`#${canvasId} is not a <canvas>`); Type guard
const isCanvas = (el: Element | null): el is HTMLCanvasElement => el instanceof HTMLCanvasElement;
Try / catch
try { await init(canvasId); } catch (e) { if (String(e).includes('not a HTML Canvas')) console.error(`#${canvasId} must be <canvas>`); else throw e; } Prevention
- Use <canvas> tags in boilerplate HTML
- Keep element ids unique across the document
- Pass the canvas element's id, not a container div's
When it happens
Trigger: Calling init with a canvas id that resolves to a non-canvas DOM element (div, span, iframe) so the dyn_into cast fails.
Common situations: Index.html updated so the element became a div or the id was reused on another element; copy-pasted boilerplate keeping the wrong tag; mistakenly passing a container element id instead of the canvas id.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- wasm-interpreter: Could not retrieve existing HTML Canvas…
- wasm-interpreter: Could not retrieve DOM document
- wasm-interpreter: Could not retrieve DOM window
- binding was of the wrong type
- Callback ' ' cannot be used with a callback decorator for…
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/7baa8951d1a761d2.
Report an issue: GitHub.
Appendix: source
Thrown at api/wasm-interpreter/src/lib.rs:399
if let Some(canvas_id) = next_id.borrow_mut().take() {
use i_slint_backend_winit::winit::platform::web::WindowAttributesExtWebSys;
use wasm_bindgen::JsCast;
let html_canvas = web_sys::window()
.expect("wasm-interpreter: Could not retrieve DOM window")
.document()
.expect("wasm-interpreter: Could not retrieve DOM document")
.get_element_by_id(&canvas_id)
.unwrap_or_else(|| {
panic!(
"wasm-interpreter: Could not retrieve existing HTML Canvas element '{}'",
canvas_id
)
})
.dyn_into::<web_sys::HtmlCanvasElement>()
.unwrap_or_else(|_| {
panic!(
"winit backend: Specified DOM element '{}' is not a HTML Canvas",
canvas_id
)
});
attrs = attrs
.with_canvas(Some(html_canvas))
// Don't activate the window by default, as that will cause the page to scroll,
// ignoring any existing anchors.
.with_active(false);
attrs
} else {
attrs
}
})
})
.build()
.unwrap();
i_slint_core::platform::set_platform(Box::new(backend))View on GitHub (pinned to bb937076de)