Skip to content

fix(rollup): load handler meta staged under file:// URLs - #4630

Open
nikolas-sapa wants to merge 2 commits into
nitrojs:v2from
nikolas-sapa:fix/handler-meta-file-url
Open

nikolas-sapa wants to merge 2 commits into
nitrojs:v2from
nikolas-sapa:fix/handler-meta-file-url

Conversation

@nikolas-sapa

Copy link
Copy Markdown

🔗 Linked issue

Fixes #4564

❓ Type of change

  • 🐞 Bug fix (a non-breaking change which fixes an issue)

📚 Description

When a Nuxt layer contains .js server routes, nitro scans and registers them but then fails to load them via the nitro-handler-meta virtual module:

ERROR Error: Could not load nitro-handler-meta:file:///path/to/project/Client/packages/Payment/server/api/payment/bankRegister2.post.js (imported by virtual:#nitro-internal-virtual/server-handlers-meta): ENOENT: no such file or directory, open 'file:///...'

The chain:

  1. #nitro-internal-virtual/server-handlers-meta generates import ...Meta from "<handler>?meta" for every scanned handler.
  2. The handlers-meta plugin's resolveId asks the host bundler to resolve the <handler> specifier. For files outside the project root (which is the normal case for server routes in Nuxt layers), the bundler reports the resolved id as a file:// URL.
  3. The plugin builds \0nitro-handler-meta:file://... and later loads it with readFile("file://...") — but fs.readFile does not understand URL strings, so it throws ENOENT even though the file exists.

Renaming the file to .ts made the error disappear only because the layer's resolver then returned a plain path; the file format itself was never the problem. It also explains the issue's second workaround: with a layer folder sharing a prefix with the base layer, the bundler's resolver caches/normalizes differently and stops returning the URL form.

This converts file:// ids back to paths with fileURLToPath before reading, mirroring what the externals plugin already does (src/rollup/plugins/externals.ts:41).

📝 Checklist

  • I have read the Contributing Guide.
  • I have included a change request file using the $ prefix (not applicable — bug fix with linked issue).
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.

`lookupNodeModuleSubpath()` reports the package root export as `"./"`, and
`join()` keeps the trailing slash, so the guessed specifier became `"pkg/"`.
Specifiers ending in `/` are a deprecated exports pattern: resolving one emits
DEP0155 and always returns undefined.

Strip the trailing slash so the root export is looked up as `"pkg"`. The guess
is still only used when it resolves back to the same file, so this cannot
introduce an incorrect external.
The `?meta` specifier is resolved by the host bundler before the
handlers-meta plugin's `resolveId` runs, and bundlers report absolute
paths as `file://` URLs when the file lives outside the project root
(e.g. server routes in Nuxt layers). The virtual id built from the
resolved id was loaded with `readFile` directly, which does not
understand URL strings and failed with ENOENT even though the file
exists. Renaming the file to `.ts` worked only because the layer's
vite resolver then returned a plain path.

Convert `file://` ids back to paths before reading.

Fixes nitrojs#4564
@nikolas-sapa
nikolas-sapa requested a review from pi0 as a code owner September 14, 2026 18:29
@vercel

vercel Bot commented Sep 14, 2026

Copy link
Copy Markdown

@nikolas-sapa is attempting to deploy a commit to the Nitro Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 52cb0714-c75d-449e-bde4-0f07abc16604

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants