Skip to content

A parent URL that ends in / (the working directory) is resolved as a file #862

Closed

Description

@fengmk2

Node.js resolves --import preloads against the working directory as a directory URL (pathToFileURL(process.cwd() + '/'), so it ends in /), and on the registerHooks() path the entry point too. resolve() in src/lib.rs reads every parent URL as a file and resolves from parent_file.parent(), so a directory parent URL resolves from the directory above it:

let directory = match parent_file {
    Some(parent_file) => parent_file
        .parent()
        .ok_or_else(|| Error::new(Status::GenericFailure, "Parent URL is not a file URL"))?,
    None => cwd.as_path(),
};

This shows up two ways:

  1. A relative --import without an extension is not found, because the TypeScript extension probing runs from the wrong directory and Node.js' fallback does not probe .ts. With @oxc-node/core@0.1.7 on Node.js 22.18.0, 24.12.0, and 26.5.0:

    $ cat setup.ts
    const s: string = "setup ran"; console.log(s);
    $ node --import @oxc-node/core/register --import ./setup ./main.ts
    Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/tmp/x/setup' imported from /tmp/x/

    An extensionless import './setup' inside main.ts does find setup.ts, so only the directory parent URL is affected. tsx runs setup.ts in both cases. ts-node's ESM loader rejects both, since it does no extension probing in ESM by default, so oxc-node is the only one where the two disagree.

  2. On main (1c23b37), with the working directory at /, file:/// has no parent, so every script fails on the registerHooks() path with Error: Parent URL is not a file URL, for example in a container without WORKDIR or a systemd service. We hit this through Vite+, which vendors 1c23b37 (cd / && vpx /tmp/h.ts on Node.js 24.12.0 and 26.5.0; the module.register() path is not affected). 0.1.7, tsx, and ts-node all run the script.

A parent URL that ends in / is the directory to resolve from. Vite+ works around it for now by passing a file URL inside that directory to createResolve and the original URL to nextResolve.

Activity

  1. added 3 commits that reference this issue on Oct 20, 2026
    86183c8
    2d68bab
    767bc6c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions