tonhowtf/omniget · error
não achei o catálogo (/Root) do documento
Error message
não achei o catálogo (/Root) do documento
What it means
When rebuilding the xref table, `rebuild_xref` must emit a trailer containing a `/Root` reference to the document catalog. If the existing trailer lacks `/Root` and neither `find_root_ref` (a `2 0 R`-style ref) nor `find_catalog` (an `obj` with `/Type /Catalog`) locates the catalog, reconstruction is impossible and this error is thrown.
Solutions
- Search the file for `/Type /Catalog`; if found but unreferenced, the heuristic failed — check whether the object number is unusual (e.g. very large) and consider patching `find_catalog`'s matching
- Verify the file is complete — a truncated tail loses both trailer and xref; re-download or re-export the source
- Try recovering the catalog from incremental updates: an earlier revision of the file may contain a valid `/Root` reference
- Use a third-party recovery tool (e.g. qpdf/mutool clean) to rebuild structure before this repair
Example fix
// before
let (bytes, objs) = rebuild_xref(&data)?;
// after
if !data.windows(15).any(|w| w == b"/Type /Catalog") {
eprintln!("no catalog object present — rebuild_xref will fail");
return Ok(());
}
let (bytes, objs) = rebuild_xref(&data)?; Defensive patterns
Strategy: validation
Validate before calling
fn has_catalog(data: &[u8]) -> bool {
data.windows(14).any(|w| w == b"/Type /Catalog")
|| data.windows(5).any(|w| w == b"/Root")
}
// require has_catalog(&data) before calling rebuild_xref on trailer-damaged files Try / catch
match rebuild_xref(&data) {
Err(e) if e.to_string().contains("/Root") => {
eprintln!("catalog missing — file is too damaged for xref-only repair; use a full recovery tool");
}
other => other?,
} Prevention
- Pre-scan for /Type /Catalog before offering xref repair to users
- Keep original files untouched — repair into a copy so incremental revisions can be retried
- Encourage re-export from the source application when the trailer is truncated
- Try qpdf --recover or mutool clean as a pre-pass on badly damaged files
When it happens
Trigger: Repairing a PDF whose trailer dictionary is missing or truncated and whose catalog object is absent, renumbered in an unrecognized way, or unreferenced — so `run`/`rebuild_xref` cannot determine the document root.
Common situations: Files cut off mid-trailer by truncation; PDFs assembled by tools that omit the trailer (linearized/exotic writers); prior failed edits that dropped or renumbered the catalog object; files recovered from disk with partially overwritten object streams.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- nenhum objeto encontrado — arquivo vazio ou cifrado
- não limpei o sumário antigo
- não achei appid para
- nao esta listado em
- não consegui medir o loudness
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/06105976eddd87a9.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pdf_repair.rs:390
let off = out.len();
out.extend_from_slice(format!("{} 0 obj\n", num).as_bytes());
out.extend_from_slice(&content);
out.extend_from_slice(b"\nendobj\n");
by_num.insert(num, (off, 0));
unpacked += 1;
}
}
tracing::debug!("[pdf-repair] {} objetos soltos de object stream", unpacked);
let max = by_num.keys().copied().max().unwrap_or(0);
let size = max + 1;
let all: Vec<(u32, usize, u16)> = by_num.iter().map(|(n, (o, g))| (*n, *o, *g)).collect();
let trailer = match last_trailer_dict(body) {
Some(d) if d.contains("/Root") => patch_trailer(&d, size),
_ => {
let root = find_root_ref(&out)
.or_else(|| find_catalog(&out, &all))
.ok_or_else(|| anyhow!("não achei o catálogo (/Root) do documento"))?;
format!("<< /Size {} /Root {} >>", size, root)
}
};
let xref_at = out.len();
out.extend_from_slice(format!("xref\n0 {}\n", size).as_bytes());
out.extend_from_slice(b"0000000000 65535 f \n");
for n in 1..size {
match by_num.get(&n) {
Some((off, gen)) => {
out.extend_from_slice(format!("{:010} {:05} n \n", off, gen).as_bytes())
}
None => out.extend_from_slice(b"0000000000 65535 f \n"),
}
}
out.extend_from_slice(b"trailer\n");
out.extend_from_slice(trailer.trim().as_bytes());
out.extend_from_slice(format!("\nstartxref\n{}\n%%EOF\n", xref_at).as_bytes());View on GitHub (pinned to 8600b91f42)