Skip to content

fix: ship the pdfjs worker so PDF CVs can be read in production - #258

Merged
JoachimLK merged 1 commit into
mainfrom
fix/pdf-worker-missing-in-build
Aug 5, 2026
Merged

fix: ship the pdfjs worker so PDF CVs can be read in production#258
JoachimLK merged 1 commit into
mainfrom
fix/pdf-worker-missing-in-build

Conversation

@JoachimLK

Copy link
Copy Markdown
Contributor

Every PDF parse in production was failing. Nitro's dependency tracer never sees pdfjs-dist's worker, because pdfjs builds that import specifier at runtime, so pdf.worker.mjs was dropped from the server bundle and each parse died with:

Setting up fake worker failed: "Cannot find module
'/app/.output/server/node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs'"

Recruiters saw this as CVs that wouldn't autofill and candidates scored 0%, because a failed parse leaves the resume text empty and the model is handed nothing to evaluate.

externals.traceInclude cannot express this — Nitro resolves the entry back through Rollup, gets the bare specifier, and passes that to nodeFileTrace as a root-relative path — so the worker is copied into the bundle from a nitro compiled hook instead.

Two related defects found while confirming the fix:

  • pdf-parse stamps "-- 1 of 3 --" page markers into extracted text by default. On an image-only CV those markers are the only text, so the document read as non-empty, was stored, and reached the model as the candidate's entire resume — a silent 0% with nothing logged.
  • parseDocument collapsed "the parser crashed" and "this document has no text" into the same null, which is how a server packaging bug spent months surfacing to users as "this CV is a scan". Callers can now tell the two apart via parseDocumentDetailed, and the extract-cv endpoint returns 503 rather than blaming the recruiter's file.

Summary

  • What does this PR change?
  • Why is this needed?

PR title must follow Conventional Commits — e.g. feat(jobs): add bulk import or fix: handle null salary. The squash-merged title is what release-please uses to generate the changelog and pick the next version. PRs with non-conventional titles are blocked by CI.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Chore

Validation

  • I tested locally
  • I added/updated relevant documentation
  • I verified multi-tenant scoping and auth behavior for affected API paths

DCO

  • All commits in this PR are signed off (Signed-off-by) via git commit -s

Every PDF parse in production was failing. Nitro's dependency tracer
never sees pdfjs-dist's worker, because pdfjs builds that import
specifier at runtime, so pdf.worker.mjs was dropped from the server
bundle and each parse died with:

  Setting up fake worker failed: "Cannot find module
  '/app/.output/server/node_modules/pdfjs-dist/legacy/build/pdf.worker.mjs'"

Recruiters saw this as CVs that wouldn't autofill and candidates scored
0%, because a failed parse leaves the resume text empty and the model is
handed nothing to evaluate.

externals.traceInclude cannot express this — Nitro resolves the entry
back through Rollup, gets the bare specifier, and passes that to
nodeFileTrace as a root-relative path — so the worker is copied into the
bundle from a nitro `compiled` hook instead.

Two related defects found while confirming the fix:

- pdf-parse stamps "-- 1 of 3 --" page markers into extracted text by
  default. On an image-only CV those markers are the only text, so the
  document read as non-empty, was stored, and reached the model as the
  candidate's entire resume — a silent 0% with nothing logged.
- parseDocument collapsed "the parser crashed" and "this document has no
  text" into the same null, which is how a server packaging bug spent
  months surfacing to users as "this CV is a scan". Callers can now tell
  the two apart via parseDocumentDetailed, and the extract-cv endpoint
  returns 503 rather than blaming the recruiter's file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@railway-app

railway-app Bot commented Aug 5, 2026

Copy link
Copy Markdown

🚅 Deployed to the reqcore-pr-258 environment in applirank

Service Status Web Updated (UTC)
applirank ✅ Success (View Logs) Aug 5, 2026 at 10:55 am

@railway-app
railway-app Bot temporarily deployed to applirank / reqcore-pr-258 August 5, 2026 10:51 Destroyed
@JoachimLK
JoachimLK merged commit 2d970e4 into main Aug 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant