flxzt/rnote · error
no page at index
Error message
no page at index '{page_i} What it means
Importing a PDF into an Image by rendering its pages to PNG. from_pdf_bytes takes a page range and looks each page up in the parsed PDF's page list; if an index in that range is not present, this error is thrown. It means the requested page index is out of bounds for the loaded document.
Solutions
- Clamp the page range to pages.len() before calling from_pdf_bytes
- Convert 1-based UI page numbers to 0-based indices (subtract 1)
- Parse the PDF first (e.g. hayro_syntax::Pdf::new) and validate page count before requesting pages
- Return a user-facing 'page N does not exist' message with the actual page count
Example fix
// before let pages = 0..10; image::Image::from_pdf_bytes(bytes, pages, zoom, None)?; // after let page_count = hayro_syntax::Pdf::new(bytes.into())?.pages().len(); let pages = 0..10.min(page_count as u32); image::Image::from_pdf_bytes(bytes, pages, zoom, None)?;
Defensive patterns
Strategy: validation
Validate before calling
let page_count = hayro_syntax::Pdf::new(bytes.clone().into())?.pages().len() as u32;
assert!(page_range.start < page_count && page_range.end <= page_count, "page range {page_range:?} exceeds {} pages", page_count); Type guard
fn page_range_in_bounds(range: std::ops::Range<u32>, page_count: usize) -> bool {
range.start < range.end && (range.end as usize) <= page_count
} Try / catch
match from_pdf_bytes(bytes, range, zoom, password) {
Ok(imgs) => imgs,
Err(e) if e.to_string().contains("no page at index") => {
eprintln!("requested pages not in document, clamping to available pages");
from_pdf_bytes(bytes, clamp_range(range, actual_count), zoom, password)?
}
Err(e) => return Err(e),
} Prevention
- Always derive the page range from the parsed PDF's page count, never from user input directly
- Convert 1-based UI page numbers to 0-based indices at the UI boundary
- Clamp ranges with .min(page_count) before conversion
- Surface the document's actual page count in import dialogs
When it happens
Trigger: Calling VectorImage::from_pdf_bytes (bitmapimage equivalent: Image::from_pdf_bytes with Pdf) with a page range like 0..10 on a PDF that has fewer pages, or using 1-based page numbers instead of 0-based indices.
Common situations: Users select 'pages 5-10' in an import dialog for a 4-page PDF; documents re-saved or truncated before import; off-by-one confusion between UI page numbers (1-based) and API indices (0-based).
Related errors
- Creating Pdf instance failed, Err
- Creating Pdf instance failed, Err
- Creating Pdf instance failed, Err
- Failed to get filename from rnote_file
- Stroke has empty widths vector.
AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08).
Data as JSON: /api/errors/e3ea6714a1041951.
Report an issue: GitHub.
Appendix: source
Thrown at crates/rnote-engine/src/strokes/bitmapimage.rs:169
} else {
format.width() * (pdf_import_prefs.page_width_perc / 100.0)
};
// calculate the page zoom based on the width of the first page.
let page_zoom = if let Some(first_page) = pages.first() {
page_width / first_page.render_dimensions().0 as f64
} else {
return Ok(vec![]);
};
let x = insert_pos[0];
let mut y = insert_pos[1];
// TODO: investigate if this can be parallelized with rayon's `par_iter()`
let pngs = page_range
.map(|page_i| {
let page = pages
.get(page_i)
.ok_or_else(|| anyhow::anyhow!("no page at index '{page_i}"))?;
let (intrinsic_width, intrinsic_height) = {
let dimensions = page.render_dimensions();
(dimensions.0 as f64, dimensions.1 as f64)
};
let width = intrinsic_width * page_zoom;
let height = intrinsic_height * page_zoom;
let render_settings = hayro::RenderSettings {
x_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom) as f32,
y_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom) as f32,
width: Some((pdf_import_prefs.bitmap_scalefactor * width).ceil() as u16),
height: Some((pdf_import_prefs.bitmap_scalefactor * height).ceil() as u16),
bg_color: vello_cpu::color::AlphaColor::WHITE,
};
// TODO: implement drawing page borders.
// Possibly with vello-cpu, since it already is a dependency of hayro
let pixmap = hayro::render(page, &interpreter_settings, &render_settings);
let png_data = pixmap.into_png()?;View on GitHub (pinned to bbc5354502)