flxzt/rnote · error

accessing imagesurface data failed, Err

Error message

accessing imagesurface data failed, Err: {e:?}

What it means

Thrown by Svg::gen_image when cairo's ImageSurface::data() returns Err. Accessing the raw pixel buffer requires the surface to be finished and in a healthy state; cairo returns an error if the surface is in an error status or the borrow rules (no live references) are violated.

Solutions

  1. Ensure the cairo::Context is dropped before calling data() — keep it in an inner scope as the code does
  2. Check for earlier render failures that put the surface into an error state
  3. Call surface.flush() before reading data if needed
  4. Log the wrapped cairo::Error for the exact status

Example fix

// before
let data = surface.data().map_err(|e| anyhow::anyhow!("accessing imagesurface data failed, Err: {e:?}"))?.to_vec();
// after
surface.flush();
let data = surface.data().map_err(|e| anyhow::anyhow!("accessing imagesurface data failed: {e:#}"))?.to_vec();
Defensive patterns

Strategy: try-catch

Validate before calling

surface.flush();
if surface.status() != cairo::Status::Success { anyhow::bail!("surface in error state: {:?}", surface.status()); }

Type guard

fn readable(surface: &cairo::ImageSurface) -> bool { surface.status() == cairo::Status::Success }

Try / catch

let data = match surface.data() {
    Ok(d) => d.to_vec(),
    Err(e) => { log::error!("surface data access failed: {e:?}"); return Err(e.into()); }
};

Prevention

When it happens

Trigger: Calling surface.data() while a cairo::Context referencing the surface is still alive (hence the inner scope), or the surface entered an error state during rendering.

Common situations: Restructuring gen_image so the Context outlives the data() call (borrow error surfaced as cairo error), or a failed render leaving the surface in an error state.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

                .context("read stream to rsvg loader failed.")?;

            let renderer = rsvg::CairoRenderer::new(&handle);
            renderer
                .render_document(
                    &cx,
                    &cairo::Rectangle::new(
                        bounds.mins[0],
                        bounds.mins[1],
                        bounds.extents()[0],
                        bounds.extents()[1],
                    ),
                )
                .map_err(|e| anyhow::anyhow!("rendering rsvg document failed, Err: {e:?}"))?;
        }

        let data = surface
            .data()
            .map_err(|e| anyhow::anyhow!("accessing imagesurface data failed, Err: {e:?}"))?
            .to_vec();

        Ok(Image {
            data: glib::Bytes::from_owned(convert_image_bgra_to_rgba(
                width_scaled,
                height_scaled,
                data,
            )),
            rectangle: Rectangle::from_p2d_aabb(bounds),
            pixel_width: width_scaled,
            pixel_height: height_scaled,
            // cairo renders to bgra8-premultiplied, but we convert it to rgba8-premultiplied
            memory_format: ImageMemoryFormat::R8g8b8a8Premultiplied,
        })
    }
}

View on GitHub (pinned to bbc5354502)