neoclide/coc.nvim · error

process.${name}() is not allowed in extension sandbox

Error message

process.${name}() is not allowed in extension sandbox

What it means

thrown by stubs installed in the extension sandbox for process methods that were removed for security (REMOVED_GLOBALS, e.g. exit, abort, kill). Extensions run isolated; calling a destructive process API raises instead of affecting the host coc.nvim process.

Source

Thrown at src/extension/loader.ts:120

  'exit',
  'kill',
]

export const consoleLogger: ILogger = {
  category: '',
  log: console.log.bind(console),
  debug: console.debug.bind(console),
  error: console.error.bind(console),
  warn: console.warn.bind(console),
  info: console.info.bind(console),
  trace: console.log.bind(console),
  fatal: console.error.bind(console),
  mark: console.log.bind(console),
}

function removedGlobalStub(name: string) {
  return () => {
    throw new Error(`process.${name}() is not allowed in extension sandbox`)
  }
}

/**
 * Process facade exposed to extensions as the `process` global and returned
 * by `require('process')` / `require('node:process')`.
 */
export function createProcessFacade(): NodeJS.Process {
  const facade: any = new (process as any).constructor()
  for (let key of Reflect.ownKeys(process)) {
    if (typeof key === 'string' && key.startsWith('_')) continue
    facade[key] = process[key]
  }
  REMOVED_GLOBALS.forEach(name => {
    facade[name] = removedGlobalStub(name)
  })
  facade['chdir'] = () => {}
  facade['umask'] = (mask?: number) => {

View on GitHub (pinned to 50e974d969)

Solutions

  1. Remove/replace the process.<name>() call in the extension code.
  2. Use the extension's proper lifecycle (deactivate/dispose) instead of process.exit.
  3. Wrap legacy dependencies so their exit paths don't run, or upgrade the dependency.
  4. Report the extension bug to its maintainer if it's third-party.

Example fix

// before (in extension)
if (!ready) process.exit(1)
// after
if (!ready) throw new Error('extension not ready')  // or return early / dispose
Defensive patterns

Strategy: try-catch

Validate before calling

// static check of extension source before load:
if (/process\.(exit|abort|kill)\s*\(/.test(extSource)) throw new Error('extension uses forbidden process API')

Try / catch

try { activateExtension(ext) } catch (e) { if (e.message.includes('is not allowed in extension sandbox')) { disableExtension(ext, e.message) } else { throw e } }

Prevention

When it happens

Trigger: An extension calls process.exit(), process.abort(), process.kill(), etc., or a transitive dependency (e.g. old exit-using libraries) invokes them at runtime inside the sandboxed loader.

Common situations: Extensions ported from plain Node.js code that assumes it can terminate the process; debug code calling process.exit in a command handler; dependency like graceful-fs-era code paths.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/9b7a9d0b8bce0f66. Report an issue: GitHub.