{"record":{"id":"1fe72c33b9a49b2c","repo":"denoland/deno","slug":"err-vm-module-status","errorCode":"ERR_VM_MODULE_STATUS","errorMessage":"Module status must not be unlinked or linking","messagePattern":"Module status must not be unlinked or linking","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/vm.js","lineNumber":601,"sourceCode":"        \"vm.SourceTextModule | vm.SyntheticModule\",\n        this,\n      );\n    }\n    this[kLinkingStatus] = null;\n  }\n\n  get identifier() {\n    return op_vm_module_get_identifier(this[kWrap]);\n  }\n\n  get context() {\n    return this[kContext];\n  }\n\n  get namespace() {\n    const status = op_vm_module_get_status(this[kWrap]);\n    if (status < 2) {\n      throw new ERR_VM_MODULE_STATUS(\"must not be unlinked or linking\");\n    }\n    return op_vm_module_get_namespace(this[kWrap]);\n  }\n\n  get status() {\n    if (this[kLinkingStatus] !== null) {\n      return this[kLinkingStatus];\n    }\n    return STATUS_NAMES[op_vm_module_get_status(this[kWrap])];\n  }\n\n  get error() {\n    if (this.status !== \"errored\") {\n      throw new ERR_VM_MODULE_STATUS(\"must be errored\");\n    }\n    return op_vm_module_get_exception(this[kWrap]);\n  }\n","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/vm.js#L583-L619","documentation":"A vm module's namespace object exists only after linking succeeds. Module#namespace reads the module status and throws ERR_VM_MODULE_STATUS('must not be unlinked or linking') while status is below Linked — i.e. before link() runs, or while a link is still in flight.","triggerScenarios":"const m = new vm.SourceTextModule(code); m.namespace — or reading namespace without awaiting the promise returned by m.link(linker).","commonSituations":"Porting vm.Script (CommonJS-style) code where no link phase exists; forgetting ESM-in-vm is asynchronous at two stages (link, then evaluate); callbacks racing the link promise and reading namespace too early.","solutions":["Await both stages: await m.link(linker); await m.evaluate(); then read m.namespace.","Check m.status before access: only read namespace when status is 'linked' or later.","Chain dependent logic off the evaluate() promise instead of running it in parallel with linking."],"exampleFix":"// before\nconst m = new vm.SourceTextModule(\"export const a = 1;\");\nm.link(linker);\nconsole.log(m.namespace); // ERR_VM_MODULE_STATUS\n\n// after\nconst m = new vm.SourceTextModule(\"export const a = 1;\");\nawait m.link(linker);\nawait m.evaluate();\nconsole.log(m.namespace.a); // 1","handlingStrategy":"validation","validationCode":"async function readyModule(m, linker) {\n  if (m.status === \"unlinked\") await m.link(linker);\n  if (m.status === \"linked\") await m.evaluate();\n  return m; // .namespace is now safe\n}","typeGuard":null,"tryCatchPattern":"try {\n  use(m.namespace);\n} catch (err) {\n  if (err.code === \"ERR_VM_MODULE_STATUS\") {\n    throw new Error(`module not ready (status: ${m.status})`, { cause: err });\n  }\n  throw err;\n}","preventionTips":["Treat link + evaluate as a mandatory pipeline before any namespace access.","Expose a single helper that returns the namespace so callers cannot skip stages.","Log m.status during development to catch lifecycle misuse early."],"tags":["vm","module-lifecycle","err-vm-module-status","esm"],"backgroundTag":"vm-module-lifecycle","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}