denoland/deno · error · Error
ERR_VM_MODULE_STATUS
ERR_VM_MODULE_STATUS
Error message
Module status must not be unlinked or linking
What it means
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.
Source
Thrown at ext/node/polyfills/vm.js:601
"vm.SourceTextModule | vm.SyntheticModule",
this,
);
}
this[kLinkingStatus] = null;
}
get identifier() {
return op_vm_module_get_identifier(this[kWrap]);
}
get context() {
return this[kContext];
}
get namespace() {
const status = op_vm_module_get_status(this[kWrap]);
if (status < 2) {
throw new ERR_VM_MODULE_STATUS("must not be unlinked or linking");
}
return op_vm_module_get_namespace(this[kWrap]);
}
get status() {
if (this[kLinkingStatus] !== null) {
return this[kLinkingStatus];
}
return STATUS_NAMES[op_vm_module_get_status(this[kWrap])];
}
get error() {
if (this.status !== "errored") {
throw new ERR_VM_MODULE_STATUS("must be errored");
}
return op_vm_module_get_exception(this[kWrap]);
}
View on GitHub (pinned to 9ad36f7a2c)
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.
Example fix
// before
const m = new vm.SourceTextModule("export const a = 1;");
m.link(linker);
console.log(m.namespace); // ERR_VM_MODULE_STATUS
// after
const m = new vm.SourceTextModule("export const a = 1;");
await m.link(linker);
await m.evaluate();
console.log(m.namespace.a); // 1 Defensive patterns
Strategy: validation
Validate before calling
async function readyModule(m, linker) {
if (m.status === "unlinked") await m.link(linker);
if (m.status === "linked") await m.evaluate();
return m; // .namespace is now safe
} Try / catch
try {
use(m.namespace);
} catch (err) {
if (err.code === "ERR_VM_MODULE_STATUS") {
throw new Error(`module not ready (status: ${m.status})`, { cause: err });
}
throw err;
} Prevention
- 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.
When it happens
Trigger: const m = new vm.SourceTextModule(code); m.namespace — or reading namespace without awaiting the promise returned by m.link(linker).
Common situations: 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.
Related errors
- ERR_VM_MODULE_ALREADY_LINKED
- ERR_VM_MODULE_NOT_MODULE
- resolve hook must return { shortCircuit: true } or call next
- load hook must return { shortCircuit: true } or call nextLoa
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/1fe72c33b9a49b2c.
Report an issue: GitHub.