Issue #126: Feature Request: Add support for .docx resume files

interviewstreet/hiring-agent · commit e0ece80 · investigation verified · 2026-10-18 · investigation cost $0.04

No open PR fixes this and merges clean

1 fix it but don't merge clean, 1 fix it partly. See the board below.

6/6
citations verified in code
194 → 28
open PRs shortlisted by cited lines
1 fix
0 merge clean · 1 partly
$0.04
investigation cost

How it breaks

The path is the model's reasoning. Each box is a citation checked against the code.

1score.py:371 ✓
CLI accepts only a PDF path
2score.py:247 ✓
main always calls the PDF handler
3pdf.py:50 ✓
Extractor opens file with pymupdf PDF path
4pdf.py:61 ✓
Failure returns None, extraction error
5requirements.txt:1 ✓
No python-docx dependency available
where it shows

What's wrong

The report is accurate. The pipeline has no .docx support. All text extraction goes through PDFHandler, which opens the file with pymupdf and converts it with the PDF-oriented to_markdown. score.py always calls extract_json_from_pdf, and it never checks the file extension.
Show full explanationNothing in requirements.txt provides python-docx. A .docx passed in is therefore treated as a PDF. It is either rejected or garbled, and extract_text_from_pdf returns None. The run then fails with "Failed to extract text from PDF". The cache-name logic also only strips ".pdf". Adding .docx needs a new extractor, dispatch by extension in score.py, and the dependency.
Model confidence: high.

How to reproduce

  1. cd into the hiring-agent repo and install requirements.txt (pymupdf only; there is no python-docx).
  2. Run: python score.py resume.docx --role <role>, using any real .docx resume.
  3. The file passes the os.path.exists check in score.py, then goes to PDFHandler.extract_json_from_pdf.
  4. pymupdf/to_markdown is applied to the .docx; extraction fails or returns nothing and the 'Failed to extract text from PDF' error is logged.
  5. Observe that no resume data is produced and no score is given.

Evidence

Each citation was checked against the code at e0ece80.

pdf.py2 citations
line 50
verified in code
with pymupdf.open(pdf_path) as doc:

The only text extractor opens the input with pymupdf and the PDF-to-markdown converter. It has no .docx branch.

line 61
verified in code
logger.error(f"An error occurred while reading the PDF: {e}")

Any failure returns None, so a .docx input ends as an extraction failure.

score.py3 citations
line 247
verified in code
resume_data = pdf_handler.extract_json_from_pdf(pdf_path)

The main flow always uses the PDF handler. There is no dispatch on file extension.

line 212
verified in code
f"cache/resumecache_{os.path.basename(pdf_path).replace('.pdf', '')}.json"

The cache and candidate names assume a .pdf extension. A .docx extension would remain in the names.

line 371
verified in code
"pdf_path", nargs="?", help="Path to the resume PDF to evaluate"

The CLI is defined as taking a PDF only.

requirements.txt1 citation
line 1
verified in code
pymupdf>=1.23.0

Only PDF libraries are listed. python-docx is not a dependency.

Pull requests

Verdicts are judged from the diff, not run. Merge status is a real git check against e0ece80.

194open PRs
28change a cited line or mention the issue
2change the cause
0fix and merge clean
#127 and #442 all change the cause. Once one is merged, the others duplicate it.
Merges clean
Conflicts or unknown
Fixes
—
Partly
—
Why each verdict

Adds python-docx, a docx text extractor with extract_json_from_docx, extension dispatch in score.py (raising on unsupported types), and extension-agnostic cache names, covering every part of the cause.

Shortlisted because: mentions the issue, changes pdf.py:50

cache_key_for uses Path.stem, so cache and candidate names no longer assume .pdf, but there is still no docx extractor, dispatch, or dependency.

Shortlisted because: changes score.py:212
26 PRs that don't fix itShow

Only hardens cache read/write encoding and still calls extract_json_from_pdf with .pdf-only name stripping.

Shortlisted because: changes score.py:212, changes score.py:247
#41 · Fix issue #40 by Anubhav200311

Adds section splitting for PDF markdown text; no docx extractor or dispatch.

Shortlisted because: changes pdf.py:50

Unpins versions in requirements.txt and does not add python-docx.

Shortlisted because: changes requirements.txt:1

Only changes cache encoding and empty-cache handling.

Shortlisted because: changes score.py:212

Changes GitHub project fetching and cache encoding; no docx extractor, dispatch, or dependency.

Shortlisted because: changes score.py:212, changes score.py:247

Changes logging to print statements only.

Shortlisted because: changes score.py:212

Adds certificate and volunteer section extraction on the PDF pipeline.

Shortlisted because: changes pdf.py:61

Adds validation that explicitly rejects any non-.pdf extension, which enforces the PDF-only behavior rather than adding docx support.

Shortlisted because: changes pdf.py:50, changes pdf.py:61

Adds YAML config plus the same .pdf-only validation; no docx extraction or dispatch.

Shortlisted because: changes pdf.py:50, changes pdf.py:61

Adds blog data fetching; extraction and name handling are unchanged.

Shortlisted because: changes score.py:212

Adds PDF validity and keyword checks and keeps the PDF-only flow and .pdf name stripping.

Shortlisted because: changes score.py:212, changes score.py:247

Closes the PyMuPDF document and adds .pdf-only validation; no docx path.

Shortlisted because: changes pdf.py:50, changes pdf.py:61

Rewrites PDF extraction and raises ValueError for non-.pdf files; no docx support.

Shortlisted because: changes pdf.py:50, changes pdf.py:61

Adds cache validity checks only.

Shortlisted because: changes score.py:212

Adds JD-based scoring and batch mode; the JD and resume are still read as PDFs and .pdf stripping is kept.

Shortlisted because: changes score.py:212

Adds CLI flags, retries, and cache metadata for the PDF flow; no docx support.

Shortlisted because: changes score.py:212

Adds Codeforces/LeetCode integration and unrelated app files; no docx support.

Shortlisted because: changes score.py:212

Adds Ollama cloud model support and relaxes the ollama version pin.

Shortlisted because: changes requirements.txt:1

Aborts on failed sections and cache errors only.

Shortlisted because: changes score.py:212

Swaps PDF extraction for a visible-text extractor to stop hidden-text injection; still PDF-only with no dispatch.

Shortlisted because: changes pdf.py:50, changes pdf.py:61

Adds a Flask UI and an OCR fallback for image PDFs; still PDF-only.

Shortlisted because: changes score.py:212

Adds role-based scoring limits and CLI args; the input is still a PDF with .pdf stripping.

Shortlisted because: changes score.py:212, changes score.py:371

Adds the rewrite stage and a --resume-json input; the basename logic strips only .pdf/.json and docx is not handled.

Shortlisted because: changes score.py:212, changes score.py:371

Passes ignore_graphics=True to the PDF markdown converter; no docx path.

Shortlisted because: changes pdf.py:50

Adds a model selection flag and benchmark script, leaving file handling unchanged.

Shortlisted because: changes score.py:212

Dead-import and config cleanup only.

Shortlisted because: changes score.py:247

What this packet does not prove

  • Citations are checked against the code. The explanation that links them, the order of the chain, and any claim about outside systems (APIs, libraries) are the model's reasoning and are not checked.
  • PR verdicts are judged from the diff, not run. No PR was applied or tested.
  • PRs were shortlisted because they change a cited line or mention the issue. A fix in another file, or a PR whose line numbers have drifted, is missed, so this is not proof that no other PR fixes it.