{"record":{"id":"86a0e9ed2e21e842","repo":"cloudflare/quiche","slug":"cannot-find-canvas","errorCode":null,"errorMessage":"cannot find canvas {}","messagePattern":"cannot find canvas (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"qlog-dancer/src/plots/mod.rs","lineNumber":186,"sourceCode":"    }\n}\n\n#[cfg(not(target_arch = \"wasm32\"))]\npub fn make_chart_bitmap_area(\n    path: &str, size: ChartSize, colors: PlotColors, margin: ChartMargin,\n) -> DrawingArea<plotters::prelude::BitMapBackend<'_>, plotters::coord::Shift> {\n    let backend = BitMapBackend::new(path, (size.width, size.height));\n    let area = backend.into_drawing_area();\n    area.fill(&colors.fill).unwrap();\n    area.margin(margin.top, margin.bottom, margin.left, margin.right)\n}\n\n#[cfg(target_arch = \"wasm32\")]\npub fn make_chart_canvas_area(\n    canvas_id: &str, colors: PlotColors, margin: ChartMargin,\n) -> plotters::drawing::DrawingArea<CanvasBackend, plotters::coord::Shift> {\n    let backend = CanvasBackend::new(canvas_id)\n        .unwrap_or_else(|| panic!(\"cannot find canvas {}\", canvas_id));\n    let area = backend.into_drawing_area();\n    area.fill(&colors.fill).unwrap();\n    area.margin(margin.top, margin.bottom, margin.left, margin.right)\n}\n\nfn make_chart_config(\n    title: &str, params: &PlotParameters, filename: &str, ds: &Datastore,\n    ty: &ChartOutputType,\n) -> ChartConfig {\n    let chart_config = ChartConfig {\n        title: title.into(),\n        input_filename: filename.into(),\n        clamp: params.clamp.clone(),\n        app_proto: ds.application_proto,\n        host: ds.host.clone(),\n        session_id: ds.session_id,\n        ty: ty.clone(),\n    };","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/cloudflare/quiche/blob/9f96daa2c22a4468b0036fb0a0a3894eee6498b8/qlog-dancer/src/plots/mod.rs#L168-L204","documentation":"In qlog-dancer's wasm (browser) build, make_chart_canvas_area panics when plotters' CanvasBackend cannot find an HTML <canvas> element with the requested id. The chart drawing area is created from a DOM canvas; a missing or mistyped id means plotting cannot proceed. Note CanvasBackend::new returns Option in this setup, hence the unwrap_or_else panic.","triggerScenarios":"Calling any plot function (plot_main_plot, plot_packet_received, plot_cc_plot, etc.) in the wasm app when the DOM has no <canvas id=\"...\"> matching the canvas_id passed to make_chart_canvas_area.","commonSituations":"HTML template and Rust plot code out of sync (renamed canvas id); plot invoked before the DOM finished loading; JS interop passing a wrong id; running the wasm app with an outdated index.html.","solutions":["Ensure the HTML contains <canvas id=\"<canvas_id>\"> exactly matching the id used in the plot call.","Run the plot code after DOMContentLoaded/onload, not before the canvas exists.","If you renamed a canvas in the HTML, update the corresponding id in the Rust plotting code (or vice versa)."],"exampleFix":"// before (html)\n<canvas id=\"main-chart-old\"></canvas>\n// after\n<canvas id=\"main-chart\"></canvas> // matches make_chart_canvas_area(\"main-chart\", ...)","handlingStrategy":"validation","validationCode":"// before calling the plot function\nlet el = web_sys::window().unwrap().document().unwrap().get_element_by_id(canvas_id);\nassert!(el.is_some(), \"canvas {} missing from DOM\", canvas_id);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep canvas ids in the HTML template in sync with the Rust plot code.","Invoke plotting only after the DOM is ready (onload / DOMContentLoaded)."],"tags":["qlog-dancer","wasm","canvas","dom"],"backgroundTag":"resource-not-found","analyzedSha":"9f96daa2c22a4468b0036fb0a0a3894eee6498b8","analyzedAt":"2026-09-08T11:27:09.536Z","contentChangedAt":"2026-09-08T11:27:09.536Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}