tonhowtf/omniget · error

não limpei o sumário antigo

Error message

não limpei o sumário antigo: {}

What it means

write_outline first calls doc.delete_outlines() to remove any pre-existing bookmark tree; if lopdf's delete fails, the error is wrapped as "não limpei o sumário antigo" ("could not delete the old outline"). Existing outlines must be cleared before building the new one so entries don't conflict.

Solutions

  1. Inspect the wrapped lopdf error in the message to identify the malformed structure.
  2. Re-save the PDF through a repair tool (qpdf --check / qpdf input output) before writing the outline.
  3. Re-export the PDF from its original source to regenerate a clean catalog.
  4. Open and re-save the document with lopdf once to normalize objects before calling write_outline.
Defensive patterns

Strategy: try-catch

Validate before calling

let doc = lopdf::Document::load(&opts.input)?;
// a loadable catalog usually means delete_outlines will succeed
let _root = doc.trailer.get(b"Root").map_err(|_| anyhow!("no catalog; repair PDF first"))?;

Try / catch

match write_outline(&opts) {
    Err(e) if e.to_string().contains("não limpei o sumário antigo") => {
        eprintln!("source PDF has broken outline structure: {:?}", e);
        // repair with qpdf or skip
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling write_outline on a PDF whose outline/catalog structure is malformed such that lopdf's delete_outlines() returns Err (e.g. catalog missing, dangling outline references).

Common situations: PDFs produced by tools that wrote a broken Outlines dictionary; hand-edited or partially rewritten PDFs; files where the Root/catalog object is damaged.

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 tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/b7143ac5a965a601. Report an issue: GitHub.

Appendix: source

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

    // A raiz /Outlines não tem título: quem é nível 0 é o /First dela.
    if let Ok(first) = doc
        .get_dictionary(root)
        .and_then(|d| d.get(b"First"))
        .and_then(Object::as_reference)
    {
        walk(&doc, first, 0, &pages, &mut out, 0);
    }
    Ok(out)
}

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);

View on GitHub (pinned to 8600b91f42)