Skip to content

Cannot read properties of undefined when requiring node:fs with hooks #60005

@BadIdeaException

Description

@BadIdeaException

Version

v22.20.0, v23.11.1, v24.8.0

Platform

Linux exports-undefined 6.8.0-84-generic #84-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep  5 22:36:38 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

module

What steps will reproduce the bug?

register.mjs:

import { registerHooks } from 'node:module';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';

function resolve(specifier, context, nextResolve) {
	const path = fileURLToPath(import.meta.url);
	const dir = dirname(path);
	switch (specifier) {
		case 'fs':
		case 'node:fs':
			specifier = join(dir, 'fs-mock.mjs');					
	}

	return nextResolve(specifier, context);
};

registerHooks({ resolve });

fs-mock.mjs:

export const constants = {
	F_OK: 42
}

index.cjs:

const fs = require('node:fs');
console.log(fs.constants.F_OK);

Run node --import=./register.mjs index.cjs.

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

Happens reliably when fs is being required as node:fs, does not happen when required as fs, or when imported.

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

Should either require fs-mock.mjs, or require original (builtin) fs module.

What do you see instead?

node:internal/modules/cjs/loader:1155
  return mod.exports;
             ^

TypeError: Cannot read properties of undefined (reading 'exports')
    at loadBuiltinWithHooks (node:internal/modules/cjs/loader:1155:14)
    at Function._load (node:internal/modules/cjs/loader:1197:20)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
    at Module.require (node:internal/modules/cjs/loader:1463:12)
    at require (node:internal/modules/helpers:147:16)
    at Object.<anonymous> (/vagrant/index.cjs:1:12)
    at Module._compile (node:internal/modules/cjs/loader:1706:14)
    at Object..js (node:internal/modules/cjs/loader:1839:10)
    at Module.load (node:internal/modules/cjs/loader:1441:32)

Additional information

Output from NODE_DEBUG=* node --import=./register.mjs index.cjs:
log.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    loadersIssues and PRs related to ES module loaders

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions