GraphiteEditor/Graphite · error
Failed to cast element to HtmlCanvasElement
Error message
Failed to cast element to HtmlCanvasElement
What it means
After `document.create_element("canvas")` succeeds, the wrapper converts the JS value to a typed `HtmlCanvasElement` with `dyn_into`, which performs a JS `instanceof`-style check. The `.expect("Failed to cast element to HtmlCanvasElement")` panics when the created object is not actually an `HTMLCanvasElement` — possible when the document is not an HTML document (XML/SVG documents produce generic elements) or a polyfilled DOM returns a mock that fails the brand check.
Source
Thrown at frontend/wrapper/src/helpers.rs:166
}
};
let canvases_obj = Object::from(canvases_obj);
for image in image_data {
let (placeholder_id, width, height) = (image.id, image.width, image.height);
let pixels = image.pixels.as_slice();
let canvas_name = placeholder_id.to_string();
let js_key = JsValue::from_str(&canvas_name);
if Reflect::has(&canvases_obj, &js_key).unwrap_or(false) || width == 0 || height == 0 {
continue;
}
let canvas: HtmlCanvasElement = document
.create_element("canvas")
.expect("Failed to create canvas element")
.dyn_into::<HtmlCanvasElement>()
.expect("Failed to cast element to HtmlCanvasElement");
canvas.set_width(width);
canvas.set_height(height);
let context: CanvasRenderingContext2d = canvas
.get_context("2d")
.expect("Failed to get 2d context")
.expect("2d context was not found")
.dyn_into::<CanvasRenderingContext2d>()
.expect("Failed to cast context to CanvasRenderingContext2d");
let clamped_pixels = wasm_bindgen::Clamped(pixels);
match ImageData::new_with_u8_clamped_array_and_sh(clamped_pixels, width, height) {
Ok(image_data_obj) => {
if context.put_image_data(&image_data_obj, 0, 0).is_err() {
error!("Failed to put image data on canvas for id: {placeholder_id}");
}
}
Err(e) => {View on GitHub (pinned to c507b35645)
Solutions
- Use `let Ok(canvas) = element.dyn_into::<HtmlCanvasElement>() else { ... continue; }` so one uncastable element skips one image instead of crashing.
- Ensure the wrapper runs in a standard HTML document in a real browser.
- In tests, prefer a real browser runner; if using jsdom, verify `document.createElement('canvas') instanceof HTMLCanvasElement` holds.
- Feature-detect before the loop: bail out early if a probe canvas fails the `instanceof` check.
Example fix
// before
let canvas: HtmlCanvasElement = document
.create_element("canvas")
.expect("Failed to create canvas element")
.dyn_into::<HtmlCanvasElement>()
.expect("Failed to cast element to HtmlCanvasElement");
// after
let element = document.create_element("canvas").unwrap_or_else(|err| {
panic!("create_element('canvas') threw {err:?}")
});
let Ok(canvas) = element.dyn_into::<HtmlCanvasElement>() else {
error!("element is not an HTMLCanvasElement; skipping image id {placeholder_id}");
continue;
}; Defensive patterns
Strategy: type-guard
Validate before calling
// TS: verify the environment yields real canvas elements
export const realCanvasElements: boolean = (() => {
try {
return document.createElement('canvas') instanceof HTMLCanvasElement;
} catch {
return false;
}
})(); Type guard
function isHtmlCanvasElement(el: unknown): el is HTMLCanvasElement {
return typeof HTMLCanvasElement !== 'undefined' && el instanceof HTMLCanvasElement;
} Prevention
- Probe instanceof HTMLCanvasElement once at startup in test/embedding environments.
- Prefer real browsers over DOM emulations for anything exercising canvas blitting.
When it happens
Trigger: Running `render_image_data_to_canvases` in an XML/SVG-mode document or DOM emulation where `createElement('canvas')` returns an object failing `instanceof HTMLCanvasElement`; web-sys and the actual host DOM disagreeing on element interfaces (heavy polyfills, patched globals).
Common situations: DOM-emulation test setups (jsdom variants returning generic Element mocks); editors embedded into SVG or XML host documents; environments where `HTMLCanvasElement` is polyfilled without proper branding.
Related errors
- Failed to create canvas element
- Failed to get canvas context
- Failed to get canvas context
- Failed to draw ellipse
- Failed to transform circle
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/e1ccfc420bf5580b.
Report an issue: GitHub.