slint-ui/slint · critical

wasm-interpreter: Could not retrieve existing HTML Canvas…

Error message

wasm-interpreter: Could not retrieve existing HTML Canvas element '{}'

What it means

During WASM interpreter initialization, the runtime looks up the DOM element whose id was given as the canvas and fails when `document.getElementById` returns nothing. The library requires a pre-existing HTML canvas element to attach rendering to. Without it the UI cannot be mounted, so init panics.

Solutions

  1. Ensure the HTML contains `<canvas id="canvas_id">` with exactly the id passed to init
  2. Call init after the DOM is ready (defer script, `DOMContentLoaded`, or render-after-mount hooks)
  3. Verify the canvas isn't removed/replaced by framework re-rendering before init
  4. Check the browser console that the script runs against the intended document (not an iframe without the canvas)

Example fix

// before
<canvas id="my-canvas"></canvas>
init("canva").await;
// after
init("my-canvas").await; // id matches the HTML element
Defensive patterns

Strategy: validation

Validate before calling

const el = document.getElementById(canvasId);
if (!el) throw new Error(`Canvas '${canvasId}' not found before init()`);

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('HTML Canvas element')) console.error(`Add <canvas id="${canvasId}"> to the page`); else throw e; }

Prevention

When it happens

Trigger: Calling `init` with a canvas_id that no element in the current document uses, or calling before the DOM element is added to the page.

Common situations: Typo or mismatch between the `<canvas id=...>` in index.html and the string passed to init; SPA frameworks removing/re-rendering the canvas before init runs; running the wasm module on a page without the expected markup.

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 slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/2c9b4898bcdfc346. Report an issue: GitHub.

Appendix: source

Thrown at api/wasm-interpreter/src/lib.rs:392

pub fn init() -> Result<(), JsValue> {
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();
    let backend = i_slint_backend_winit::Backend::builder()
        .with_spawn_event_loop(true)
        .with_window_attributes_hook(|mut attrs| {
            NEXT_CANVAS_ID.with(|next_id| {
                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 {

View on GitHub (pinned to bb937076de)