Node.js keeps one context object for the whole resolve hook chain and
merges whatever a hook passes to nextResolve into it, both for
module.registerHooks() and for module.register(). The NODE_PATH fallback
retries a bare specifier with a synthetic parentURL inside each NODE_PATH
entry. When every retry failed and the hook rethrew the original error, a
hook registered after it, which runs first, read the synthetic parentURL
from its context. A tsconfig paths resolver then looked for the alias
target under the project's node_modules and failed with
ERR_MODULE_NOT_FOUND.
The hook now saves the importer's parentURL before the retries and puts
it back on the context when they finish, whether a retry resolves or not.
The retries still pass { ...context, parentURL } to nextResolve, so the
caller's export conditions are kept. The TypeScript and Rust CLIs embed
the same hook source, and the shared golden flag is regenerated.
The new tests run the scenario from the issue in both stacks: a hook
loaded with --import after the NODE_OPTIONS flag resolves an `@/` alias
from context.parentURL. The test hook falls back to module.register()
where module.registerHooks() is missing, so the Node.js 22.13 CI job
covers the async loader variant as well.
Closespnpm/pnpm#16979