flxzt/rnote · error

accessing image surface data failed, Err

Error message

accessing image surface data failed, Err: {e:?}

What it means

image_surface.data() returned Err in gen_with_cairo, i.e. Cairo could not give access to the surface's underlying byte buffer after the draw function ran. In Cairo, this happens when the surface is in an error state (e.g. creation failed earlier or the draw func wrote to an invalid context).

Solutions

  1. Check the draw_func for Cairo calls that can put the context into an error state (e.g. invalid patterns, huge coordinates).
  2. Verify the surface was created successfully and dimensions are sane before drawing.
  3. Check cairo surface status (image_surface.status()) after drawing to get the underlying error.
  4. Ensure sufficient memory; very large surfaces can fail on map.

Example fix

// before
let data = image_surface.data().map_err(|e| anyhow!("accessing image surface data failed, Err: {e:?}"))?;
// after
if image_surface.status() != cairo::Status::Success {
    return Err(anyhow!("surface in error state: {:?}", image_surface.status()));
}
let data = image_surface.data().map_err(|e| anyhow!("accessing image surface data failed, Err: {e:?}"))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// rust
if image_surface.status() != cairo::Status::Success {
    return Err(anyhow!("surface in error state before data access: {:?}", image_surface.status()));
}

Type guard

fn surface_is_readable(s: &cairo::ImageSurface) -> bool {
    s.status() == cairo::Status::Success && s.width() > 0 && s.height() > 0
}

Try / catch

let data = image_surface.data().map_err(|e| {
    anyhow!("accessing image surface data failed (status: {:?}): {e:?}", image_surface.status())
})?;

Prevention

When it happens

Trigger: Calling gen_with_cairo whose draw_func triggered a Cairo error (invalid surface, context error state) so that data() cannot be mapped.

Common situations: Panics or Cairo errors inside draw_func leaving the context in error state; surface creation with degenerate dimensions; running out of memory mapping the buffer.

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/616f6c756ad5c1ef. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/image.rs:357

        .map_err(|e| {
            anyhow::anyhow!(
                "creating image surface with dimensions ({}, {}) failed, Err: {e:?}",
                width_scaled,
                height_scaled,
            )
        })?;

        {
            let cairo_cx = cairo::Context::new(&image_surface)?;
            cairo_cx.scale(image_scale, image_scale);
            cairo_cx.translate(-bounds.mins[0], -bounds.mins[1]);
            // Apply the draw function
            draw_func(&cairo_cx)?;
        }

        let data = image_surface
            .data()
            .map_err(|e| anyhow::anyhow!("accessing image surface 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,
        })
    }

    /// Generates an image with a provided closure that draws onto a [piet_cairo::CairoRenderContext].
    pub fn gen_with_piet<F>(draw_func: F, bounds: Aabb, image_scale: f64) -> anyhow::Result<Self>

View on GitHub (pinned to bbc5354502)