Skip to content

fix: delegate extensionless files to nextLoad instead of short-circui…#7

Open
fgiova wants to merge 1 commit into
tapjs:mainfrom
fgiova:fix/loadsync-extensionless-source
Open

fix: delegate extensionless files to nextLoad instead of short-circui…#7
fgiova wants to merge 1 commit into
tapjs:mainfrom
fgiova:fix/loadsync-extensionless-source

Conversation

@fgiova

@fgiova fgiova commented Jun 15, 2026

Copy link
Copy Markdown

This pull request updates the module loader hooks to ensure compatibility with Node.js strict validation (Node >= 24.13), particularly when handling extensionless files. The main change is to delegate extensionless file loading to nextLoad with a commonjs format hint, instead of short-circuiting, which prevents validation errors. The tests have also been updated and expanded to verify this behavior in both sync and async load hooks.

Loader hook improvements:

  • Changed the extensionless file handling in both the sync (loadSync) and async (load) hooks to delegate to nextLoad with { format: 'commonjs' } instead of returning a short-circuit result. This avoids ERR_INVALID_RETURN_PROPERTY_VALUE errors under Node.js strict validation. [1] [2]

Testing updates:

  • Updated existing tests in test/hooks.mjs to expect delegation to nextLoad and to validate that the correct format and source are returned for extensionless files.
  • Added a new test in test/hooks.cts to specifically verify that extensionless files loaded via sync hooks (using --import) do not trigger strict validation errors in Node.js >= 24.13.

…ting

On Node >= 24.13 the sync `module.registerHooks({ load })` path strictly
validates the hook return: a `shortCircuit: true` result must carry a
`source`. The extensionless-file branch in both `loadSync` and `load`
returned `{ format: 'commonjs', shortCircuit: true }` with no `source`,
so any extensionless CommonJS bin (cdk, cdklocal, npx, ...) required
while the loader is active crashed with ERR_INVALID_RETURN_PROPERTY_VALUE.

Delegate to `nextLoad(url, { ...context, format: 'commonjs' })` instead:
this preserves the commonjs format hint while letting the default step
supply a valid `source`, satisfying strict validation. Behaviour on
Node < 24.13 (async register path) is unchanged.

Adds an integration test that require()s an extensionless bin through the
sync registerHooks path and asserts no strict-validation error.

Fixes tapjs#6
tapjs#6
@fgiova fgiova mentioned this pull request Jun 15, 2026
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