{"record":{"id":"67303579d0700e3a","repo":"MadsLorentzen/ai-job-search","slug":"expected-expected-pages-page-s-found-actual-p","errorCode":null,"errorMessage":"expected {expected_pages} page(s), found {actual_pages} (extractor: {extractor})","messagePattern":"expected (.+?) page\\(s\\), found (.+?) \\(extractor: (.+?)\\)","errorType":"exception","errorClass":"VerificationError","httpStatus":null,"severity":"error","filePath":"tools/verify_pdf.py","lineNumber":112,"sourceCode":"\n    extracted_text, actual_pages, extractor = extract_text_layer(pdf_path)\n\n    # Write dump *before* the checks so a failed verification still leaves a .txt\n    if dump_text is not None:\n        dump_path = Path(dump_text)\n        try:\n            dump_path.parent.mkdir(parents=True, exist_ok=True)\n            dump_path.write_text(\n                extracted_text if extracted_text.endswith(\"\\n\") else extracted_text + \"\\n\",\n                encoding=\"utf-8\",\n            )\n        except OSError as exc:\n            raise VerificationError(\n                f\"could not write --dump-text to {dump_path}: {exc}\"\n            ) from exc\n\n    if expected_pages is not None and actual_pages != expected_pages:\n        raise VerificationError(\n            f\"expected {expected_pages} page(s), found {actual_pages} (extractor: {extractor})\"\n        )\n\n    normalized = normalize_text(extracted_text)\n    if len(normalized) < min_chars:\n        raise VerificationError(\n            f\"text layer has {len(normalized)} character(s); expected at least {min_chars} \"\n            f\"(extractor: {extractor})\"\n        )\n\n    for required in required_text:\n        if normalize_text(required) not in normalized:\n            raise VerificationError(\n                f\"text layer is missing required text: {required!r} (extractor: {extractor})\"\n            )\n    return extractor, extracted_text, actual_pages\n\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/MadsLorentzen/ai-job-search/blob/79cd383e58f0af7948c7c6462a3a289e9b67421e/tools/verify_pdf.py#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run pdfinfo on the actual PDF and reconcile your expected_pages with reality","Fix the generation step so it deterministically produces the intended page count (page breaks, CSS @page, \\\\newpage)","Pass expected_pages=None if page count is not actually a contract of the test","Use dump-text/--dump-text to inspect what content landed on unexpected pages"],"exampleFix":"// before\nverify_pdf(pdf, expected_pages=3)  # PDF actually has 4 pages\n// after\nverify_pdf(pdf, expected_pages=4)  # after fixing template overflow\n# or drop the assertion\nverify_pdf(pdf, min_chars=500, required_text=('Total',))","handlingStrategy":"validation","validationCode":"import subprocess\ndef page_count(pdf: str) -> int:\n    out = subprocess.run(['pdfinfo', pdf], capture_output=True, text=True, check=True).stdout\n    return parse_page_count(out)\n\nactual = page_count(str(pdf))\nverify_pdf(pdf, expected_pages=actual if actual else None)","typeGuard":null,"tryCatchPattern":"try:\n    verify_pdf(pdf, expected_pages=3)\nexcept VerificationError as e:\n    if 'page(s)' in str(e):\n        print(e)  # includes both counts and extractor; adjust expectation or generator","preventionTips":["Pin page-count expectations only where pagination is deterministic","Use dump-text to see which content spills to extra pages","Recompute expected_pages from the template in CI rather than hardcoding"],"tags":["pdf","page-count","verification","assertion"],"backgroundTag":null,"analyzedSha":"79cd383e58f0af7948c7c6462a3a289e9b67421e","analyzedAt":"2026-08-27T21:51:12.330Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}