[Documents skill] Page-cited DOCX Q&A can trigger full PDF/PNG rendering; renderer lacks page-range and timeout support

Open 💬 0 comments Opened Aug 13, 2026 by jy6888

What version of the Codex App are you using?

26.803.10989

Affected bundled Documents skill snapshot: 26.805.11740

What subscription do you have?

ChatGPT Pro

What platform is your computer?

Windows x64

What issue are you seeing?

The bundled Documents skill can route ordinary read-only DOCX Q&A through a full-document visual-rendering pipeline when page-number citations are required.

The upper-level guidance contains three interacting requirements:

  1. tasks/read_review.md labels DOCX -> PNG (internally via PDF) as the primary or "golden" method for reading/reviewing an existing DOCX.
  2. The Q&A citation guidance requires a page number verified against the latest render/inspection.
  3. For huge documents, the skill says to render and inspect key pages first.

However, the canonical render_docx.py cannot render a requested page range. Its CLI has no --first-page / --last-page options, and its call to pdf2image.convert_from_path() supplies neither first_page nor last_page. It therefore rasterizes every page after converting the whole DOCX to PDF.

The result is an upper/lower-layer mismatch: the skill asks the agent to inspect only relevant pages, while the packaged renderer only exposes an all-pages operation. Requiring verified page-number citations can therefore make a content lookup fall into a full DOCX -> PDF -> all-page PNG workflow.

On Windows, the cost is amplified by renderer failure handling:

  • soffice is invoked by a literal executable name rather than capability discovery.
  • subprocess.run() has no timeout.
  • If direct DOCX -> PDF fails, the script attempts DOCX -> ODT -> PDF.
  • An agent can spend substantial time on renderer discovery/failure/retry before falling back to Microsoft Word or direct OOXML extraction.

In the observed task, the user only asked for information from a long Word document and needed source page numbers. Text extraction succeeded quickly, but the overall task took about seven minutes because the workflow attempted rendering and image inspection to establish pagination.

This report is about routing and renderer capability, not only the already-reported malformed LibreOffice URI. It is related to #27957 and #30649, but neither issue covers the inability to request a page range or the read-only Q&A routing mismatch.

What steps can reproduce the bug?

  1. Use the bundled Documents skill snapshot 26.805.11740.
  2. Provide a long DOCX (a synthetic 100+ page document is sufficient).
  3. Ask a content-only question whose answer appears in one section, and require a page-number source citation.
  4. Follow the skill's read/review and citation instructions.
  5. Invoke the packaged renderer as documented:
python render_docx.py input.docx --output_dir out
  1. Observe that the script:
  • converts the entire DOCX to PDF;
  • calls convert_from_path(pdf_path, ...) without page bounds;
  • creates PNG output for every page;
  • offers no CLI option to request only the relevant page(s).
  1. On a Windows machine without LibreOffice on PATH, observe that the literal soffice launch fails before any page image is produced. The subprocess also has no timeout for cases where the renderer starts but hangs.

Relevant implementation shape:

proc = subprocess.run(
    cmd,
    check=False,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,
    env=env,
)
convert_from_path(
    pdf_path,
    dpi=dpi,
    fmt="png",
    thread_count=8,
    output_folder=out_dir,
    paths_only=True,
    output_file="page",
)

The CLI exposes output directory, width, height, DPI, PDF emission, and verbosity, but no page selector.

What is the expected behavior?

The workflow should classify the task before rendering:

  • Content-only lookup: extract OOXML/text directly; do not create PDF or PNG files.
  • Exact page lookup: use a pagination-aware backend to locate the matching range/page without rasterizing the document.
  • Targeted visual inspection: render only the identified page range.
  • Full-document render: reserve for explicit full visual audits and final layout-sensitive create/edit QA.

The renderer should support page-bounded output, for example:

--first-page 12 --last-page 14

and pass the values through to the rasterizer.

It should also:

  • discover supported render backends instead of assuming a literal soffice command;
  • fail fast with a clear missing-backend message;
  • use per-stage timeouts;
  • log stage duration and output count;
  • stop when a stage produces zero artifacts;
  • avoid an automatic ODT fallback unless it is explicitly useful for the requested task.

Page-number citations are valuable and should remain available, but obtaining a page number should not imply full-document visual rendering.

Additional information

Local timing from an isolated diagnostic on the same host:

  • Direct DOCX OOXML content extraction: approximately 2.62 ms.
  • Microsoft Word pagination/export through Python COM: approximately 2.0 s end-to-end for the smoke document.
  • PDF export portion: approximately 220 ms.
  • One-page raster smoke test: approximately 719 ms.

These timings show that Microsoft Word and rasterization themselves were not responsible for the seven-minute end-to-end delay. The delay came from choosing an unnecessarily broad rendering route and spending time in failed or mismatched renderer stages.

A local workaround now classifies DOCX requests and uses direct extraction, pagination-only lookup, targeted page rendering, or full QA as separate routes. The bundled skill should provide that distinction so users do not need a local replacement.

View original on GitHub ↗