docling-project / docling-project/docling

pdfium outline is silently truncated at 15 levels

Open Beginner friendly
#4,161 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
66.4k
Forks
4.8k
Avg merge
2d 21h
Merged PRs (30d)
84

Description

### Bug

`extract_outline_from_pdfium()` calls `pdoc.get_toc()` without arguments. pypdfium2
walks the outline recursively and defaults to `max_depth=15`, dropping every entry
below that level with only a log line:

```
Maximum recursion depth 15 reached (subtree skipped).
```

The other extractor in the same module, `extract_outline_from_docling_parse()`, walks
iteratively and is unbounded — `test_outline_deep_chain_does_not_raise_recursion_error`
asserts it handles 5000 levels. So the two extractors silently disagree on any document
whose table of contents is deeper than 15, and `PyPdfiumDocumentBackend` loses those
entries.

### Steps to reproduce

Build a one-page PDF whose outline is a chain 20 levels deep, then:

```python
import pypdfium2 as pdfium
from docling.utils.pdf_outline import extract_outline_from_pdfium

doc = pdfium.PdfDocument("deep_outline.pdf")
print(len(list(doc.get_toc()))) # 15 <- default bound
print(len(list(doc.get_toc(max_depth=128)))) # 20
print(len(extract_outline_from_pdfium(doc))) # 15 <- entries 16..20 are gone
```

Observed on both pypdfium2 4.30.0 and 5.13.0; the signature `get_toc(max_depth=15, ...)`
is the same in each.

### Docling version

2.124.0

### Python version

3.13.15

Contributor guide

Open the contributing guide

Research direction

Start in docling/utils/pdf_outline.py with extract_outline_from_pdfium() and compare its pypdfium2 get_toc() call with extract_outline_from_docling_parse(). Run test_outline_deep_chain_does_not_raise_recursion_error and reproduce the 20-level outline case; done means the pdfium extractor retains entries beyond level 15 and the regression is covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.