{"record":{"id":"da8fdd081e72c0ed","repo":"denoland/deno","slug":"err-vm-module-not-module","errorCode":"ERR_VM_MODULE_NOT_MODULE","errorMessage":"Provided module is not an instance of Module","messagePattern":"Provided module is not an instance of Module","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/vm.js","lineNumber":680,"sourceCode":"    }\n\n    const specifiers = [];\n    const linkerPromises = [];\n    for (let i = 0; i < requests.length; i++) {\n      const { specifier, attributes } = requests[i];\n      ArrayPrototypePush(specifiers, specifier);\n      const p = PromiseResolve(\n        linker(specifier, this, { attributes, assert: attributes }),\n      );\n      ArrayPrototypePush(linkerPromises, p);\n    }\n    const resolvedModules = await SafePromiseAll(linkerPromises);\n\n    const wraps = [];\n    for (let i = 0; i < resolvedModules.length; i++) {\n      const m = resolvedModules[i];\n      if (!isModule(m)) {\n        throw new ERR_VM_MODULE_NOT_MODULE();\n      }\n      if (m.context !== this[kContext]) {\n        throw new ERR_VM_MODULE_DIFFERENT_CONTEXT();\n      }\n      ArrayPrototypePush(wraps, m[kWrap]);\n    }\n\n    // Record this module's resolutions before recursing so a dependency that\n    // imports back into this module finds it already in `visited`.\n    op_vm_module_link(this[kWrap], specifiers, wraps);\n\n    for (let i = 0; i < resolvedModules.length; i++) {\n      await resolvedModules[i][kLinkGraph](linker, visited);\n    }\n  }\n\n  evaluate(options = { __proto__: null }) {\n    try {","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/vm.js#L662-L698","documentation":"Thrown by vm.Module#link() when a linker callback resolves with a value that is not a vm.SourceTextModule or vm.SyntheticModule instance. After awaiting all linker promises, the polyfill duck-checks each result with isModule() (a non-null object carrying the internal kWrap symbol, vm.js:554). Node's V8 binding raises the same code, so behavior matches node:vm.","triggerScenarios":"Calling `module.link(async (specifier) => ...)` where the callback returns a module namespace object (`import * as ns`), a source string, a Buffer/Uint8Array of code, undefined (missing return), a plain object like {exports}, or a module created by a different loaded copy of the vm polyfill so the internal kWrap symbol does not match.","commonSituations":"Writing a custom linker that loads files with fs.readFileSync(path) and returns the buffer or the file content instead of wrapping it in `new vm.SourceTextModule(code, {identifier: specifier})`; forgetting the `return` keyword in an arrow-function linker; returning `null` for dependencies the developer considers optional; returning `require(...)` results instead of vm module instances.","solutions":["Make the linker return a `new vm.SourceTextModule(loadedCode, { identifier: specifier })` or a `new vm.SyntheticModule([...], cb)` instance for every specifier it is given","Check for a missing `return` in the linker arrow function — an implicit undefined is the most common cause","For virtual/static dependencies, return a SyntheticModule that setExport()s the needed values","Make sure only one copy of the node:vm polyfill creates modules (no duplicate vm module instances across realms/bundles)"],"exampleFix":"// before\nmod.link(async (specifier) => {\n  const code = fs.readFileSync(resolve(dir, specifier)); // returns Buffer -> ERR_VM_MODULE_NOT_MODULE\n});\n// after\nmod.link(async (specifier) => {\n  const code = fs.readFileSync(resolve(dir, specifier), 'utf8');\n  return new vm.SourceTextModule(code, { identifier: specifier });\n});","handlingStrategy":"type-guard","validationCode":"const m = await linker(spec, mod, attrs);\nif (!(m instanceof vm.SourceTextModule || m instanceof vm.SyntheticModule)) {\n  throw new TypeError(`linker returned ${typeof m} for ${spec}; expected a vm module`);\n}","typeGuard":"const isVmModule = (v) =>\n  v instanceof vm.SourceTextModule || v instanceof vm.SyntheticModule;","tryCatchPattern":"mod.link(linker).catch((e) => {\n  if (e.code === 'ERR_VM_MODULE_NOT_MODULE') {\n    // inspect linker return values; log which specifier failed\n  } else throw e;\n});","preventionTips":["Wrap the linker so every return path is type-guarded before resolution","Never return namespaces, strings, or null from a linker — throw your own descriptive error instead","Keep a single copy of the node:vm module in bundles so instanceof checks stay reliable"],"tags":["vm","esm","module-linking","node-compat"],"backgroundTag":"vm-module-linking","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}