flxzt/rnote · error
Downcasting Svg surface content failed, Err
Error message
Downcasting Svg surface content failed, Err: {e:?} What it means
Thrown by Svg::gen_with_cairo when the Box<dyn Any> returned by finish_output_stream() cannot be downcast to Vec<u8>. The stream backing the SVG surface must be the Vec<u8> originally supplied; a mismatch means the surface's stream is not the expected type.
Solutions
- Ensure the SvgSurface was created with SvgSurface::for_stream(width, height, Vec::new()) and the stream was never swapped
- Downcast to the actual stream type used (e.g. File) if a custom stream was set
- Use downcast_ref first to inspect the concrete type when debugging
Example fix
// before
.downcast::<Vec<u8>>().map_err(|e| anyhow::anyhow!("Downcasting Svg surface content failed, Err: {e:?}"))?
// after
match stream.downcast::<Vec<u8>>() {
Ok(bytes) => bytes,
Err(any) => anyhow::bail!("unexpected stream type: {:?}", any.type_id()),
} Defensive patterns
Strategy: type-guard
Type guard
fn is_vec_stream(any: &Box<dyn Any>) -> bool { any.is::<Vec<u8>>() } Try / catch
let bytes = stream.downcast::<Vec<u8>>().map_err(|e| anyhow::anyhow!("stream type mismatch: {:?}", e.type_id()))?; Prevention
- Always create SvgSurface::for_stream with a Vec<u8> and never replace it
- Keep surface creation and stream finishing in the same function so types stay aligned
When it happens
Trigger: finish_output_stream() returns a Box<dyn Any> whose inner type differs from the Vec<u8> given to SvgSurface::for_stream — e.g. the stream was replaced via set_custom_output_stream or the surface came from another source.
Common situations: Refactoring code to use a custom output stream without updating the downcast, or reusing generic surface-finish helper code on a surface not created with a Vec<u8> stream.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Creating svg surface with dimensions
- Finishing Svg surface output stream failed, Err
- Generating doc svg failed, returned None.
- engine snapshot is not a JSON object.
- stroke components is not a JSON array.
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/14b664e52eea512f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-engine/src/svg.rs:139
svg_surface.set_document_unit(cairo::SvgUnit::Px);
{
let cairo_cx = cairo::Context::new(&svg_surface)?;
// cairo only draws elements with positive coordinates, so we need to translate the content here
cairo_cx.translate(-bounds.mins[0], -bounds.mins[1]);
// apply the draw function
draw_func(&cairo_cx)?;
}
let content = String::from_utf8(
*svg_surface
.finish_output_stream()
.map_err(|e| {
anyhow::anyhow!("Finishing Svg surface output stream failed, Err: {e:?}")
})?
.downcast::<Vec<u8>>()
.map_err(|e| {
anyhow::anyhow!("Downcasting Svg surface content failed, Err: {e:?}")
})?,
)?;
let svg_data = rnote_compose::utils::remove_xml_header(&content);
let mut group = svg::node::element::Group::new().add(svg::node::Blob::new(svg_data));
// translate the content back to it's original position
group.assign(
"transform",
format!("translate({} {})", bounds.mins[0], bounds.mins[1]),
);
Ok(Self {
svg_data: rnote_compose::utils::svg_node_to_string(&group)?,
bounds,
})
}
/// Generate an Svg with piet, using the `piet_cairo` backend and cairo's SvgSurface.
///View on GitHub (pinned to bbc5354502)