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

  1. Change the element with that id to a `<canvas>` element in the HTML
  2. Pass the id of the actual `<canvas>` element to init instead of a container div
  3. Ensure ids are unique so getElementById resolves the canvas, not another element
  4. 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

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


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)