tonhowtf/omniget · error

página {} não existe

Error message

página {} não existe

What it means

write_outline maps each outline entry's e.page (1-based) to a page object id via pages.get(&e.page); if that page doesn't exist it falls back to the first page, and if the document has no pages at all it throws "página {} não existe" ("page {} does not exist"). Since page existence was checked earlier, this mainly fires on out-of-range page numbers combined with an edge-case page map.

Solutions

  1. Validate every entry's page is within 1..=page_count before calling write_outline.
  2. Clamp or adjust out-of-range entry pages in your own code before building OutlineOptions.
  3. Regenerate the entries from the actual PDF's page list instead of hardcoding.

Example fix

// before
entries.push(Entry { page: 42, .. });
// after
let page_count = lopdf::Document::load(&path)?.get_pages().len() as u32;
let page = entry.page.min(page_count).max(1);
entries.push(Entry { page, .. });
Defensive patterns

Strategy: validation

Validate before calling

let page_count = lopdf::Document::load(&opts.input)?.get_pages().len() as u32;
for e in &entries {
    assert!((1..=page_count).contains(&e.page), "entry page {} out of 1..{}", e.page, page_count);
}

Prevention

When it happens

Trigger: Calling write_outline with an OutlineEntry whose page number exceeds the document's page count (and the fallback lookup also fails).

Common situations: Hardcoded bookmark page numbers that don't match the current document; entries generated for a different revision of the PDF; off-by-one mistakes (0 vs 1-based page numbers).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/b0a57d454f1dcc8b. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/pdf_write.rs:778

}

pub fn write_outline(opts: &OutlineOptions) -> anyhow::Result<WriteItem> {
    let mut doc = load(&opts.input, "")?;
    let pages: BTreeMap<u32, lopdf::ObjectId> = doc.get_pages();
    if pages.is_empty() {
        return Err(anyhow!("documento sem páginas"));
    }
    doc.delete_outlines()
        .map_err(|e| anyhow!("não limpei o sumário antigo: {}", e))?;

    let entries = normalize_levels(&opts.entries);
    // Pilha com o id do último item de cada nível, para pendurar os filhos.
    let mut parents: Vec<u32> = Vec::new();
    for e in &entries {
        let page_id = *pages
            .get(&e.page)
            .or_else(|| pages.values().next())
            .ok_or_else(|| anyhow!("página {} não existe", e.page))?;
        let parent = if e.level == 0 {
            None
        } else {
            parents.get(e.level as usize - 1).copied()
        };
        let bookmark = lopdf::Bookmark::new(e.title.clone(), [0.0, 0.0, 0.0], 0, page_id);
        let id = doc.add_bookmark(bookmark, parent);
        parents.truncate(e.level as usize);
        parents.push(id);
    }
    // `build_outline` monta a árvore e devolve o id, mas quem aponta para
    // ela é o catálogo — sem isto o leitor não mostra sumário nenhum.
    if let Some(outline_id) = doc.build_outline() {
        let root = doc
            .trailer
            .get(b"Root")
            .and_then(Object::as_reference)
            .map_err(|e| anyhow!("documento sem catálogo: {}", e))?;

View on GitHub (pinned to 8600b91f42)