Skip to content

fix: declare the disjoint Node range pdf-parse actually supports - #71

Merged
jack-arturo merged 1 commit into
mainfrom
fix/node-engine-range
Aug 12, 2026
Merged

fix: declare the disjoint Node range pdf-parse actually supports#71
jack-arturo merged 1 commit into
mainfrom
fix/node-engine-range

Conversation

@jack-arturo

Copy link
Copy Markdown
Member

Follow-up to #70, addressing the P2 Codex raised there. The finding is correct and I verified it independently.

The problem

pdf-parse@2.4.5 declares:

"engines": { "node": ">=20.16.0 <21 || >=22.3.0" }

That range is disjoint. Our package.json said >=20.16.0, so we claimed support for versions pdf-parse rejects:

Node our old range pdf-parse
20.16.0 ok ok
21.0.0 ok NO
21.7.3 ok NO
22.0.0 ok NO
22.2.0 ok NO
22.3.0 ok ok
24.15.0 ok ok

On those four, users hit an engine-strict install failure or find PDF extraction unavailable at runtime.

The README section added in #70 repeated the same overclaim ("20.16.0 or newer") — and since #70 added README.md to the files allowlist, that text now ships inside the published tarball.

Why CI could not have caught it

The matrix pins 22.x, which resolves to a current 22 release far past 22.3. The gap is structurally invisible to a floating matrix — no amount of green CI would have surfaced it.

The fix

  • package.json engines.node>=20.16.0 <21 || >=22.3.0
  • README states the real range, names the two gaps, and explains they are inherited from pdf-parse rather than chosen
  • AGENTS.md updated to match

Drift guard

__tests__/unit/engine-range.test.ts reads pdf-parse's engines from node_modules and asserts ours never admits a version pdf-parse rejects.

This is the part that matters beyond today's fix: the range is inherited from a dependency, so it will rot silently the next time pdf-parse moves it. A hardcoded string in package.json has no mechanism to notice.

Verified the test actually catches the bug — reverting engines to >=20.16.0 fails it, naming 21.0.0, 21.7.3, 22.0.0, 22.2.0.

semver was present only as an undeclared transitive dependency; it and @types/semver are now proper devDependencies. Neither reaches consumers — the files allowlist excludes tests, and the tarball is unchanged at 80 files / 483 kB.

Verification

Local Node 24.15.0: lint clean, build OK, 284/284 tests across 28 suites.

🤖 Generated with Claude Code

package.json claimed `>=20.16.0`, but pdf-parse@2.4.5 declares
`>=20.16.0 <21 || >=22.3.0` — a disjoint range. We were therefore
claiming support for Node 21.x and 22.0-22.2, where an engine-strict
install fails or PDF extraction is unavailable. The README's "20.16.0 or
newer" repeated the same overclaim, and that README ships inside the
published tarball.

CI could not have caught this: the matrix pins `22.x`, which resolves to
a current 22 release far past 22.3, so the gap is invisible to it.

Adds __tests__/unit/engine-range.test.ts, which reads pdf-parse's own
engines field from node_modules and fails if ours ever admits a version
pdf-parse rejects. Verified it fails against the previous `>=20.16.0`,
naming 21.0.0, 21.7.3, 22.0.0 and 22.2.0. This matters because the range
is inherited from a dependency and will otherwise rot silently the next
time pdf-parse moves it.

semver was only present as an undeclared transitive; it and @types/semver
are now proper devDependencies. Neither reaches consumers — the `files`
allowlist excludes tests.

Reported by Codex on #70.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jack-arturo
jack-arturo merged commit 4976b71 into main Aug 12, 2026
15 checks passed
@jack-arturo
jack-arturo deleted the fix/node-engine-range branch August 12, 2026 01:08
@jack-arturo

Copy link
Copy Markdown
Member Author

Shipped in 2.0.0. Verified in the published tarball:

$ npm pack @verygoodplugins/mcp-evernote@2.0.0
$ node -p "require('./package/package.json').engines"
{ node: '>=20.16.0 <21 || >=22.3.0' }

Credit where it's due: this came from the Codex review on #70, and it was a genuinely good catch. The overclaim would otherwise have shipped inside 2.0.0 — both as the engines gate and as the README text, which #70 had just added to the files allowlist.

It's also the kind of defect a green CI run actively disguises. The matrix pins 22.x, which resolves to a current 22 release far past 22.3, so the 21.x / 22.0–22.2 gap was structurally invisible to it. No amount of passing builds would have surfaced it.

Hence the drift guard rather than just the one-line fix: the range is inherited from a dependency, so a hardcoded string has no way to notice when pdf-parse moves it next. __tests__/unit/engine-range.test.ts reads pdf-parse's own engines from node_modules and fails if ours ever admits a version it rejects — confirmed to fail against the old >=20.16.0, naming 21.0.0, 21.7.3, 22.0.0, 22.2.0.

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