MadsLorentzen/ai-job-search · error · VerificationError

expected {expected_pages} page(s), found {actual_pages} (ext

Error message

expected {expected_pages} page(s), found {actual_pages} (extractor: {extractor})

What it means

Raised by verify_pdf() when the expected_pages argument was provided and the page count extracted from the PDF differs. The message includes both counts and which extractor (e.g. pdftotext) reported them, since page-count sources can vary.

Source

Thrown at tools/verify_pdf.py:112

    extracted_text, actual_pages, extractor = extract_text_layer(pdf_path)

    # Write dump *before* the checks so a failed verification still leaves a .txt
    if dump_text is not None:
        dump_path = Path(dump_text)
        try:
            dump_path.parent.mkdir(parents=True, exist_ok=True)
            dump_path.write_text(
                extracted_text if extracted_text.endswith("\n") else extracted_text + "\n",
                encoding="utf-8",
            )
        except OSError as exc:
            raise VerificationError(
                f"could not write --dump-text to {dump_path}: {exc}"
            ) from exc

    if expected_pages is not None and actual_pages != expected_pages:
        raise VerificationError(
            f"expected {expected_pages} page(s), found {actual_pages} (extractor: {extractor})"
        )

    normalized = normalize_text(extracted_text)
    if len(normalized) < min_chars:
        raise VerificationError(
            f"text layer has {len(normalized)} character(s); expected at least {min_chars} "
            f"(extractor: {extractor})"
        )

    for required in required_text:
        if normalize_text(required) not in normalized:
            raise VerificationError(
                f"text layer is missing required text: {required!r} (extractor: {extractor})"
            )
    return extractor, extracted_text, actual_pages

View on GitHub (pinned to 79cd383e58)

Solutions

  1. Run pdfinfo on the actual PDF and reconcile your expected_pages with reality
  2. Fix the generation step so it deterministically produces the intended page count (page breaks, CSS @page, \\newpage)
  3. Pass expected_pages=None if page count is not actually a contract of the test
  4. Use dump-text/--dump-text to inspect what content landed on unexpected pages

Example fix

// before
verify_pdf(pdf, expected_pages=3)  # PDF actually has 4 pages
// after
verify_pdf(pdf, expected_pages=4)  # after fixing template overflow
# or drop the assertion
verify_pdf(pdf, min_chars=500, required_text=('Total',))
Defensive patterns

Strategy: validation

Validate before calling

import subprocess
def page_count(pdf: str) -> int:
    out = subprocess.run(['pdfinfo', pdf], capture_output=True, text=True, check=True).stdout
    return parse_page_count(out)

actual = page_count(str(pdf))
verify_pdf(pdf, expected_pages=actual if actual else None)

Try / catch

try:
    verify_pdf(pdf, expected_pages=3)
except VerificationError as e:
    if 'page(s)' in str(e):
        print(e)  # includes both counts and extractor; adjust expectation or generator

Prevention

When it happens

Trigger: Calling verify_pdf(path, expected_pages=N) where pdfinfo/pdf parsing yields a different page count: off-by-one page generation, merged/split documents, or a generator (LaTeX, reportlab, wkhtmltopdf) emitting a different number of pages than expected.

Common situations: Content overflows to an extra page in generated reports; cover pages or appendices added/removed; expected_pages hardcoded in a test while the template changed; locale/paper-size differences altering pagination.

Related errors


AI-assisted analysis of MadsLorentzen/ai-job-search@79cd383e58 (2026-08-27). Data as JSON: /api/errors/67303579d0700e3a. Report an issue: GitHub.