{"record":{"id":"5b7356496b8dac82","repo":"neoclide/coc.nvim","slug":"coc-nvim-requires-node-js-vm-modules-support-for-e","errorCode":null,"errorMessage":"coc.nvim requires Node.js VM modules support for ESM extensions; start Node with --experimental-vm-modules","messagePattern":"coc\\.nvim requires Node\\.js VM modules support for ESM extensions; start Node with --experimental-vm-modules","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/extension/esm.ts","lineNumber":32,"sourceCode":" * bridged with `vm.SyntheticModule`. Node must start with\n * `--experimental-vm-modules` for the VM module API to be available.\n */\n\nexport type ExtensionModuleFormat = 'commonjs' | 'module' | 'json' | 'native'\n\nexport type ResolvedExtensionModule =\n  | { type: 'builtin'; id: string }\n  | { type: 'coc-api'; id: 'coc.nvim' }\n  | { type: 'file'; filename: string; format: ExtensionModuleFormat }\n\nconst Module: any = require('module')\n\n/**\n * Fail only when ESM VM support is actually required.\n */\nexport function ensureVMModules(): void {\n  if (typeof vm.SourceTextModule !== 'function' || typeof vm.SyntheticModule !== 'function') {\n    throw new Error(\n      'coc.nvim requires Node.js VM modules support for ESM extensions; ' +\n      'start Node with --experimental-vm-modules'\n    )\n  }\n}\n\nconst packageTypeCache = new Map<string, 'module' | 'commonjs' | undefined>()\n\nfunction getPackageType(dirname: string): 'module' | 'commonjs' | undefined {\n  let dir = dirname\n  while (true) {\n    let pkgFile = path.join(dir, 'package.json')\n    if (fs.existsSync(pkgFile)) {\n      let key = pkgFile\n      if (packageTypeCache.has(key)) return packageTypeCache.get(key)\n      let type: 'module' | 'commonjs' | undefined\n      try {\n        let obj = JSON.parse(fs.readFileSync(pkgFile, 'utf8'))","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/extension/esm.ts#L14-L50","documentation":"ensureVMModules guards ESM extension loading: Node's vm module must expose SourceTextModule and SyntheticModule, which only exist when Node runs with --experimental-vm-modules. Without that flag, loading ESM extensions inside the VM runtime is impossible, so it throws immediately.","triggerScenarios":"Loading an ESM extension (loadSourceTextModule, createSyntheticModule, or loadESMEntry paths) on a Node.js build started without --experimental-vm-modules, or on a Node version where the flags/classes don't exist.","commonSituations":"Launching vim/neovim with a default node binary lacking the flag; using a Node version where the experimental flag was renamed/removed (Node >= 22 needs no flag, very old Node lacks support); custom node binaryPath in coc config missing the flag.","solutions":["Start Node with --experimental-vm-modules (e.g. set NODE_OPTIONS=--experimental-vm-modules).","Upgrade to Node 22+ where VM modules no longer require the flag.","Check coc's node binaryPath configuration points at the intended Node version.","Alternatively, use the CommonJS build of the extension instead of its ESM entry."],"exampleFix":"// before\n$ vim  # node started without vm module support\n// after\n$ export NODE_OPTIONS=\"--experimental-vm-modules\"\n$ vim  # or use Node >= 22 which enables vm modules by default","handlingStrategy":"validation","validationCode":"const vm = require('vm')\nif (typeof vm.SourceTextModule !== 'function' || typeof vm.SyntheticModule !== 'function') {\n  // set NODE_OPTIONS=--experimental-vm-modules or upgrade to Node >= 22 before loading ESM extensions\n  process.env.NODE_OPTIONS = (process.env.NODE_OPTIONS || '') + ' --experimental-vm-modules'\n}","typeGuard":"function hasVmModules(v: typeof import('vm')): boolean {\n  return typeof (v as any).SourceTextModule === 'function' && typeof (v as any).SyntheticModule === 'function'\n}","tryCatchPattern":"try {\n  await loadEsmExtension(entry)\n} catch (e) {\n  if (e.message.includes('--experimental-vm-modules')) {\n    logger.error('Restart Node with --experimental-vm-modules or use Node >= 22; falling back to CJS loader')\n    return loadCjsExtension(entry)\n  } else throw e\n}","preventionTips":["Launch coc's Node with --experimental-vm-modules (NODE_OPTIONS) when using ESM extensions.","Prefer Node >= 22 where vm modules work without the flag.","Document the flag requirement wherever a custom node binaryPath is configured.","Feature-check vm.SourceTextModule at startup instead of failing mid-load."],"tags":["nodejs","esm","environment","configuration"],"backgroundTag":"missing-node-flag","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}