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

  1. Check module.loaded before calling load(); skip if already true
  2. Prefer Module._load() or require(), which consult the cache for you
  3. 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

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


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/01d8e632240d3e26. Report an issue: GitHub.