denoland/deno · error · Error
Module already loaded
Error message
Module already loaded
What it means
CommonJS Module#load() marks a module loaded after evaluation; calling load() again on the same Module instance throws 'Module already loaded'. require() normally shields you via the module cache, so this error signals cache bypass: manual Module#load calls, custom _load overrides, or hook code re-loading an existing instance.
Source
Thrown at ext/node/polyfills/01_require.js:1910
* as `ts-node/register`.
* @param {string[]} requests List of modules to preload
*/
Module._preloadModules = function (requests) {
if (!ArrayIsArray(requests) || requests.length === 0) {
return;
}
const parent = new Module("internal/preload", null);
// All requested files must be resolved against cwd
parent.paths = Module._nodeModulePaths(process.cwd());
for (let i = 0; i < requests.length; i++) {
parent.require(requests[i]);
}
};
Module.prototype.load = function (filename) {
if (this.loaded) {
throw new Error("Module already loaded");
}
// Canonicalize the path so it's not pointing to the symlinked directory
// in `node_modules` directory of the referrer.
// When load hooks are active, the file may not exist on disk (virtual
// modules), so we fall back to the original filename.
let hasLoadHooks = false;
if (hookEntries.length > 0 && !insideLoadHook) {
for (let i = 0; i < hookEntries.length; i++) {
if (hookEntries[i].load !== null) {
hasLoadHooks = true;
break;
}
}
}
if (hasLoadHooks) {
try {
this.filename = op_require_real_path(filename);View on GitHub (pinned to 89f33cbef2)
Solutions
- Check module.loaded before calling load(); skip if already true
- Prefer Module._load() or require(), which consult the cache for you
- If you genuinely need re-execution, construct a fresh Module and manage the cache yourself instead of re-loading the instance
Example fix
// before
const m = Module._cache[filename];
m.load(filename); // Error: Module already loaded
// after
const m = Module._cache[filename];
if (m && !m.loaded) {
m.load(filename);
} Defensive patterns
Strategy: type-guard
Validate before calling
const cached = Module._cache[filename];
if (cached && !cached.loaded) {
cached.load(filename);
} else if (!cached) {
const m = new Module(filename, null);
m.load(filename);
} Type guard
function isLoadableModule(m: unknown): m is { load(filename: string): void; loaded: boolean } {
return m != null && typeof m === "object" && "loaded" in m && "load" in m && !(m as { loaded: boolean }).loaded;
} Prevention
- Prefer require()/Module._load() which handle caching correctly
- Never call Module#load on objects you did not construct in the same code path
- If you manipulate the cache, delete the entry before re-loading rather than reusing the instance
When it happens
Trigger: Fetching a cached module (Module._cache[filename]) and calling module.load(filename) on it; a patched Module._load that returns existing modules but still invokes load; double-loading inside registerHooks load implementations.
Common situations: Hand-rolled CJS interop in transpilers or bundlers; test harnesses that manipulate the module cache; monkey-patching Module internals for hot-reload style tooling.
Related errors
- resolve hook must return { shortCircuit: true } or call next
- load hook must return { shortCircuit: true } or call nextLoa
- BenchContext::end() has already been invoked
- Object is not a valid image or a path to an image. `Deno.jup
- Request url protocol must be 'http:' or 'https:': received '
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/01d8e632240d3e26.
Report an issue: GitHub.