MadsLorentzen/ai-job-search · error · VerificationError

text layer has {len(normalized)} character(s); expected at l

Error message

text layer has {len(normalized)} character(s); expected at least {min_chars} (extractor: {extractor})

What it means

Raised when the normalized text extracted from the PDF is shorter than the min_chars threshold (default 1). This catches scanned/image-only PDFs or documents whose text layer is empty, since normalize_text collapses whitespace before measuring length.

Source

Thrown at tools/verify_pdf.py:118

        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


def build_parser():
    parser = argparse.ArgumentParser(
        description="Verify a PDF's page count and ATS-readable text layer."
    )
    parser.add_argument("pdf", type=Path, help="PDF file to verify")
    parser.add_argument("--pages", type=int, help="required exact page count")

View on GitHub (pinned to 79cd383e58)

Solutions

  1. Inspect the PDF with `pdftotext file.pdf -` to confirm what text is extractable
  2. If the PDF is scanned images, add an OCR step (ocrmypdf --force-ocr) before verification
  3. Lower min_chars to a realistic threshold for the document
  4. If text should exist, fix the generator (embed real fonts/text instead of outlined or rasterized text)

Example fix

# before
verify_pdf(scan.pdf, min_chars=1000)  # image-only scan, no text layer
# after
subprocess.run(['ocrmypdf', '--force-ocr', 'scan.pdf', 'scan_ocr.pdf'], check=True)
verify_pdf('scan_ocr.pdf', min_chars=1000)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
def has_text_layer(pdf: str, min_chars: int = 1) -> bool:
    out = subprocess.run(['pdftotext', pdf, '-'], capture_output=True, text=True)
    return len(' '.join(out.stdout.split())) >= min_chars

if not has_text_layer(pdf, min_chars):
    subprocess.run(['ocrmypdf', '--force-ocr', pdf, pdf], check=True)

Try / catch

try:
    verify_pdf(pdf, min_chars=1000)
except VerificationError as e:
    if 'character(s)' in str(e):
        run_ocr(pdf)  # then retry verification

Prevention

When it happens

Trigger: Calling verify_pdf(path, min_chars=N) on a PDF with no or tiny extractable text: image-only scans, PDFs where text is rendered as glyphs/outlines, password-protected files whose text extraction returns nothing, or a min_chars set higher than the document's actual character count.

Common situations: A pipeline that generates PDFs via a print-to-PDF of images produces no text layer; OCR step missing; extractor fallback not installed so text comes back empty; min_chars tuned for English text applied to a short localized document.

Related errors


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