{"record":{"id":"b7143ac5a965a601","repo":"tonhowtf/omniget","slug":"n-o-limpei-o-sum-rio-antigo","errorCode":null,"errorMessage":"não limpei o sumário antigo: {}","messagePattern":"não limpei o sumário antigo: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf_write.rs","lineNumber":769,"sourceCode":"    // A raiz /Outlines não tem título: quem é nível 0 é o /First dela.\n    if let Ok(first) = doc\n        .get_dictionary(root)\n        .and_then(|d| d.get(b\"First\"))\n        .and_then(Object::as_reference)\n    {\n        walk(&doc, first, 0, &pages, &mut out, 0);\n    }\n    Ok(out)\n}\n\npub fn write_outline(opts: &OutlineOptions) -> anyhow::Result<WriteItem> {\n    let mut doc = load(&opts.input, \"\")?;\n    let pages: BTreeMap<u32, lopdf::ObjectId> = doc.get_pages();\n    if pages.is_empty() {\n        return Err(anyhow!(\"documento sem páginas\"));\n    }\n    doc.delete_outlines()\n        .map_err(|e| anyhow!(\"não limpei o sumário antigo: {}\", e))?;\n\n    let entries = normalize_levels(&opts.entries);\n    // Pilha com o id do último item de cada nível, para pendurar os filhos.\n    let mut parents: Vec<u32> = Vec::new();\n    for e in &entries {\n        let page_id = *pages\n            .get(&e.page)\n            .or_else(|| pages.values().next())\n            .ok_or_else(|| anyhow!(\"página {} não existe\", e.page))?;\n        let parent = if e.level == 0 {\n            None\n        } else {\n            parents.get(e.level as usize - 1).copied()\n        };\n        let bookmark = lopdf::Bookmark::new(e.title.clone(), [0.0, 0.0, 0.0], 0, page_id);\n        let id = doc.add_bookmark(bookmark, parent);\n        parents.truncate(e.level as usize);\n        parents.push(id);","sourceCodeStart":751,"sourceCodeEnd":787,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf_write.rs#L751-L787","documentation":"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.","triggerScenarios":"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).","commonSituations":"PDFs produced by tools that wrote a broken Outlines dictionary; hand-edited or partially rewritten PDFs; files where the Root/catalog object is damaged.","solutions":["Inspect the wrapped lopdf error in the message to identify the malformed structure.","Re-save the PDF through a repair tool (qpdf --check / qpdf input output) before writing the outline.","Re-export the PDF from its original source to regenerate a clean catalog.","Open and re-save the document with lopdf once to normalize objects before calling write_outline."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let doc = lopdf::Document::load(&opts.input)?;\n// a loadable catalog usually means delete_outlines will succeed\nlet _root = doc.trailer.get(b\"Root\").map_err(|_| anyhow!(\"no catalog; repair PDF first\"))?;","typeGuard":null,"tryCatchPattern":"match write_outline(&opts) {\n    Err(e) if e.to_string().contains(\"não limpei o sumário antigo\") => {\n        eprintln!(\"source PDF has broken outline structure: {:?}\", e);\n        // repair with qpdf or skip\n    }\n    other => other?,\n}","preventionTips":["Run qpdf --check on third-party PDFs before modifying them.","Avoid hand-editing PDF structures; always round-trip through a rewriting tool.","Pre-normalize suspicious inputs by loading and saving once with lopdf."],"tags":["pdf","outline","corrupt-file","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}