{"record":{"id":"a9b308da0c284530","repo":"denoland/deno","slug":"err-module-link-mismatch","errorCode":"ERR_MODULE_LINK_MISMATCH","errorMessage":"Expected ${requests.length} modules, got ${modules.length}","messagePattern":"Expected (.+?) modules, got (.+?)","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/vm.js","lineNumber":795,"sourceCode":"  }\n\n  get dependencySpecifiers() {\n    if (this[kDependencySpecifiers] === undefined) {\n      this[kDependencySpecifiers] = ObjectFreeze(\n        ArrayPrototypeMap(this[kModuleRequests], (r) => r.specifier),\n      );\n    }\n    return this[kDependencySpecifiers];\n  }\n\n  linkRequests(modules) {\n    if (this.status !== \"unlinked\") {\n      throw new ERR_VM_MODULE_STATUS(\"must be unlinked\");\n    }\n    validateArray(modules, \"modules\");\n    const requests = this[kModuleRequests];\n    if (modules.length !== requests.length) {\n      throw new ERR_MODULE_LINK_MISMATCH(\n        `Expected ${requests.length} modules, got ${modules.length}`,\n      );\n    }\n    // Validate each provided module first (type + context), then check for\n    // cache-key collisions: two requests sharing (specifier, attributes)\n    // must map to the same module instance, matching Node's V8 binding\n    // behavior. We use this single pass to keep the error precedence\n    // identical to Node's tests.\n    const seen = new SafeMap();\n    const specifiers = [];\n    const wraps = [];\n    for (let i = 0; i < modules.length; i++) {\n      const m = modules[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();","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/vm.js#L777-L813","documentation":"Thrown by SourceTextModule#linkRequests(modules) when the provided array length differs from module.moduleRequests.length (vm.js:793-798). Every static import/exports request in the source must be answered with exactly one module, in the same order as moduleRequests.","triggerScenarios":"Source has two imports (`import 'a'; import 'b'`) but the modules array has one entry; passing modules in a different pipeline that filtered or deduplicated them; hand-writing the array and forgetting a request; a build step generating the module source after the array was computed, adding or removing an import; passing an empty array for a module that does have imports.","commonSituations":"Plugin loaders where the source text is templated per environment but the dependency array is static; tests that copy a modules array between test cases whose sources differ; caching moduleRequests from an older version of the source; assuming import.meta or dynamic import() entries appear in moduleRequests (only static requests do, which shifts expected counts).","solutions":["Derive the array from the module itself: `mod.linkRequests(mod.moduleRequests.map(r => resolveModule(r.specifier)))` so lengths always match","Log `mod.moduleRequests.map(r => r.specifier)` and diff against the modules array before calling","Regenerate the dependency list whenever sourceText changes; never hardcode the count","Treat a length mismatch as a bug signal in the bundler/generator, not a runtime condition to catch"],"exampleFix":"// before\nmod.linkRequests([modA]); // source has two imports -> mismatch\n// after\nconst mods = mod.moduleRequests.map((r) => resolveModule(r.specifier));\nmod.linkRequests(mods);","handlingStrategy":"validation","validationCode":"const mods = mod.moduleRequests.map((r) => resolve(r.specifier, r.attributes));\nif (mods.length !== mod.moduleRequests.length) throw new Error('resolver dropped entries');\nmod.linkRequests(mods);","typeGuard":null,"tryCatchPattern":"try { mod.linkRequests(mods); }\ncatch (e) {\n  if (e.code === 'ERR_MODULE_LINK_MISMATCH') {\n    const want = mod.moduleRequests.map((r) => r.specifier);\n    throw new Error(`resolved ${mods.length}, source wants ${want.length}: [${want}]`);\n  } else throw e;\n}","preventionTips":["Derive the modules array from mod.moduleRequests itself rather than a parallel list","Regenerate dependency arrays whenever the source text changes","Treat length mismatches as generator bugs: fail loudly, don't catch-and-pad"],"tags":["vm","module-linking","deno-extension","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"}