{"record":{"id":"33e47fffceca2da0","repo":"tonhowtf/omniget","slug":"documento-sem-p-ginas","errorCode":null,"errorMessage":"documento sem páginas","messagePattern":"documento sem páginas","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/pdf_write.rs","lineNumber":766,"sourceCode":"            walk(doc, next, level, pages, out, depth + 1);\n        }\n    }\n    // 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);","sourceCodeStart":748,"sourceCodeEnd":784,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/pdf_write.rs#L748-L784","documentation":"write_outline loads the PDF, collects its pages via doc.get_pages(), and refuses to proceed when the page map is empty (\"document without pages\"). A PDF with no page objects cannot have bookmarks attached, so the library aborts early rather than writing an outline into a degenerate document.","triggerScenarios":"Calling write_outline with opts.input pointing to an empty, corrupted, or non-page-containing PDF (get_pages returns an empty BTreeMap).","commonSituations":"Passing a 0-byte or truncated file that lopdf still parses; a PDF whose page tree was stripped (e.g. some generated template files); accidentally passing a non-PDF file that lopdf loads as an empty document.","solutions":["Check the input file is a valid, non-empty PDF with pages before calling write_outline.","Re-export/repair the source PDF from its origin application.","Verify you passed the correct path in opts.input (not a different/empty file)."],"exampleFix":"// before\nwrite_outline(&OutlineOptions { input: path.into(), .. })?;\n// after\nlet doc = lopdf::Document::load(path)?;\nif doc.get_pages().is_empty() { bail!(\"input has no pages\"); }\nwrite_outline(&OutlineOptions { input: path.into(), .. })?;","handlingStrategy":"validation","validationCode":"let doc = lopdf::Document::load(&opts.input)?;\nif doc.get_pages().is_empty() {\n    return Err(anyhow!(\"{}: input PDF has no pages\", opts.input));\n}","typeGuard":null,"tryCatchPattern":"match write_outline(&opts) {\n    Err(e) if e.to_string().contains(\"documento sem páginas\") => {\n        eprintln!(\"skipping: input has no pages\");\n        // fall back to skipping this file\n    }\n    other => other?,\n}","preventionTips":["Validate input PDFs (non-zero size, loadable, has pages) before processing.","Sanity-check files after download (size > 0, %PDF header).","Keep a quarantine path for degenerate documents instead of failing the whole batch."],"tags":["pdf","validation","empty-document","rust"],"backgroundTag":"empty-required-field","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"}