flxzt/rnote · error

finishing piet context failed, Err

Error message

finishing piet context failed, Err: {e:?}

What it means

Thrown by Svg::gen_with_piet_cairo_backend when piet_cx.finish() on the piet_cairo CairoRenderContext returns a piet::Error. piet defers some rendering work (text layout buffers, etc.) to finish(); failures there mean piet could not complete the render on the underlying cairo context.

Solutions

  1. Check font availability and validity for piet text drawing (TextLayout/text rendering is a common finish() failure source)
  2. Verify the cairo context is healthy before wrapping it in a CairoRenderContext
  3. Inspect the piet::Error variant (e.g. BackendError wrapping cairo) for the root cause
  4. Simplify draw_func to isolate which piet call triggers the failure

Example fix

// before
piet_cx.finish().map_err(|e| anyhow::anyhow!("finishing piet context failed, Err: {e:?}"))
// after
piet_cx.finish().map_err(|e| anyhow::anyhow!("finishing piet context failed: {e:#}"))?;
Ok(())
Defensive patterns

Strategy: try-catch

Try / catch

match piet_cx.finish() {
    Ok(()) => Ok(()),
    Err(piet::Error::BackendError(e)) => Err(anyhow::anyhow!("piet backend (cairo) failed: {e:?}")),
    Err(e) => Err(anyhow::anyhow!("piet finish failed: {e}")),
}

Prevention

When it happens

Trigger: draw_func performs piet operations that fail on flush — e.g. invalid text layouts, unsupported text features, or an error already recorded on the cairo context during drawing.

Common situations: Rendering stroke text with fonts unavailable on the system, drawing piet primitives that map to failing cairo ops, or cairo context already in an error state when the piet context finishes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/6e20990485b497c0. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/svg.rs:170

            bounds,
        })
    }

    /// Generate an Svg with piet, using the `piet_cairo` backend and cairo's SvgSurface.
    ///
    /// This might be preferable to the `piet_svg` backend, because especially text alignment and sizes can be different
    /// with it.
    pub fn gen_with_piet_cairo_backend<F>(draw_func: F, bounds: Aabb) -> anyhow::Result<Self>
    where
        F: FnOnce(&mut piet_cairo::CairoRenderContext) -> anyhow::Result<()>,
    {
        let cairo_draw_fn = |cairo_cx: &cairo::Context| {
            let mut piet_cx = piet_cairo::CairoRenderContext::new(cairo_cx);
            // Apply the draw function
            draw_func(&mut piet_cx)?;
            piet_cx
                .finish()
                .map_err(|e| anyhow::anyhow!("finishing piet context failed, Err: {e:?}"))
        };

        Self::gen_with_cairo(cairo_draw_fn, bounds)
    }

    pub fn draw_to_cairo(&self, cx: &cairo::Context) -> anyhow::Result<()> {
        let svg_data = rnote_compose::utils::wrap_svg_root(
            self.svg_data.as_str(),
            Some(self.bounds),
            Some(self.bounds),
            false,
        );
        let stream = gio::MemoryInputStream::from_bytes(&glib::Bytes::from(svg_data.as_bytes()));
        let handle = rsvg::Loader::new()
            .with_unlimited_size(true)
            .read_stream(&stream, None::<&gio::File>, None::<&gio::Cancellable>)
            .context("reading stream to rsvg loader failed.")?;
        let renderer = rsvg::CairoRenderer::new(&handle);

View on GitHub (pinned to bbc5354502)