Skip to content

import-in-the-middle causes exception when creating ERR_MODULE_NOT_FOUND message #52987

Open
@timfish

Description

@timfish

Version

v22.1.0

Platform

All

Subsystem

module

What steps will reproduce the bug?

This was triggered by a combination of import-in-the-middle and tsx, but below is a minimal reproduction without either of those.

  • import-in-the-middle sets parentURL to node build-ins (node:*).
  • tsx tries to resolve files that do not exist

The

hook.mjs

export async function resolve(specifier, context, nextResolve) {
    specifier = 'file:///dost-not-exist.mjs';
    context.parentURL = 'node:util';
    return nextResolve(specifier, context);
}

index.mjs

import { register } from "node:module";

register('./hook.js',  import.meta.url);
await import("node:util");

Which gives the following error:

TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file
    at fileURLToPath (node:internal/url:1491:11)
    at finalizeResolution (node:internal/modules/esm/resolve:265:42)
    at moduleResolve (node:internal/modules/esm/resolve:924:10)
    at defaultResolve (node:internal/modules/esm/resolve:1148:11)
    at nextResolve (node:internal/modules/esm/hooks:750:28)
    at resolve (data:application/javascript;base64,CiAgICBleHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZShzcGVjaWZpZXIsIGNvbnRleHQsIG5leHRSZXNvbHZlKSB7CiAgICAgIHNwZWNpZmllciA9ICdmaWxlOi8vL2Rvc3Qtbm90LWV4aXN0Lm1qcyc7CiAgICAgIGNvbnRleHQucGFyZW50VVJMID0gJ25vZGU6dXRpbCc7CiAgICAgIHJldHVybiBuZXh0UmVzb2x2ZShzcGVjaWZpZXIsIGNvbnRleHQpOwogICAgfQo=:5:14)
    at nextResolve (node:internal/modules/esm/hooks:750:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:238:30)
    at MessagePort.handleMessage (node:internal/modules/esm/worker:199:24)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:821:20) {
  code: 'ERR_INVALID_URL_SCHEME'
}

This is caused by this code where base is node:util:

throw new ERR_MODULE_NOT_FOUND(
path || resolved.pathname, base && fileURLToPath(base), resolved);

How often does it reproduce? Is there a required condition?

Every time

What is the expected behavior? Why is that the expected behavior?

This should throw a valid ERR_MODULE_NOT_FOUND error

What do you see instead?

It's throwing while creating the message

Additional information

This was made incredibly difficult to debug because you can't debug loader hooks!

Credit to @nwalters512 for the back and forth debugging with me!

Metadata

Metadata

Assignees

No one assigned

    Labels

    esmIssues and PRs related to the ECMAScript Modules implementation.loadersIssues and PRs related to ES module loaders

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions