neoclide/coc.nvim · error
Unsupported module type "${ext}" for ${cacheKey}
Error message
Unsupported module type "${ext}" for ${cacheKey} What it means
thrown by the sandbox module loader's load() when a module's file extension isn't one it supports (.json, .node, .js, .cjs, empty, .mjs). ESM (.mjs) gets a dedicated error; anything else is outright unsupported in the sandboxed require implementation.
Source
Thrown at src/extension/loader.ts:255
if (request === 'coc.nvim') return this.runtime.api
if (this.isBuiltin(request)) return this.loadBuiltin(request)
let resolved = resolveExtensionModule(this.runtime, request, parent.filename, 'require')
if (resolved.type === 'file' && resolved.format === 'module') {
throw requireESMError(resolved.filename)
}
// Builtins and coc.nvim are handled above, so resolution always yields a
// file module here.
return this.load((resolved as any).filename, parent)
}
public load(filename: string, parent?: ExtensionCommonJSModule, isMain = false): unknown {
const cacheKey = this.normalizeFilename(filename)
const ext = path.extname(cacheKey).toLowerCase()
if (ext === '.json') return this.loadJson(cacheKey, parent)
if (ext === '.node') return this.loadNative(cacheKey, parent)
if (ext === '.js' || ext === '.cjs' || ext === '') return this.loadJavaScript(cacheKey, parent)
if (ext === '.mjs') throw requireESMError(cacheKey)
throw new Error(`Unsupported module type "${ext}" for ${cacheKey}`)
}
/**
* Load a native addon outside the VM. The addon is dlopen'd by Node and its
* exports are cached in the runtime module cache.
*/
public loadNative(filename: string, parent?: ExtensionCommonJSModule): unknown {
const cacheKey = this.normalizeFilename(filename)
const cached = this.runtime.cjsModules.get(cacheKey)
if (cached) return cached.exports
const nodeModule = new Module(cacheKey)
nodeModule.filename = cacheKey
nodeModule.paths = Module._nodeModulePaths(path.dirname(cacheKey))
const nativeLoad = Module._extensions && Module._extensions['.node']
if (typeof nativeLoad !== 'function') {
throw new Error(`Unsupported native addon: ${cacheKey}`)
}
nativeLoad(nodeModule, cacheKey)View on GitHub (pinned to 50e974d969)
Solutions
- Compile the module to .js/.cjs before requiring it in the extension.
- Rename/emit the file with a supported extension (.js, .cjs, .json).
- Use the ESM entry (.mjs) only if your loader path supports it — otherwise bundle to CJS.
- Don't require non-code assets via require; read them with fs and parse manually (e.g. .wasm via WebAssembly API if exposed).
Example fix
// before
const helper = require('./helper.ts')
// after (compile first)
const helper = require('./helper.js') Defensive patterns
Strategy: validation
Validate before calling
const ext = path.extname(modulePath).toLowerCase()
const supported = ['.json', '.node', '.js', '.cjs', '.mjs', '']
if (!supported.includes(ext)) throw new Error(`unsupported ext ${ext}; compile to .js first`) Type guard
function hasSupportedExt(f) { return ['', '.js', '.cjs', '.json', '.node', '.mjs'].includes(path.extname(f).toLowerCase()) } Try / catch
try { const m = sandboxRequire(p) } catch (e) { if (e.message.startsWith('Unsupported module type')) { /* bundle/compile the module, then retry */ } else { throw e } } Prevention
- Ship extensions as compiled .js/.cjs, never raw .ts
- Don't require() non-code assets; read them with fs
- Pre-bundle wasm/native code paths
When it happens
Trigger: require('.../.ts') or .tsx/.jsx/.wasm/.mts files from an extension; require resolving a file with an unusual extension; tools trying to load WebAssembly via require.
Common situations: Extensions importing TypeScript source directly instead of compiled JS; monorepo code resolving uncompiled assets; attempted require of .wasm or template files.
Related errors
- Unsupported native addon: ${cacheKey}
- process.${name}() is not allowed in extension sandbox
- Cannot use process.umask() to change mask (read-only)
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/2724c030370e3a45.
Report an issue: GitHub.