neoclide/coc.nvim · error

Cannot use process.umask() to change mask (read-only)

Error message

Cannot use process.umask() to change mask (read-only)

What it means

thrown by the sandboxed process facade when an extension calls process.umask(mask) with an argument to change the umask; reading umask() without arguments is allowed, changing it is read-only in the sandbox. coc.nvim prevents extensions from mutating host process state.

Source

Thrown at src/extension/loader.ts:140

}

/**
 * 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) => {
    if (typeof mask !== 'undefined') {
      throw new Error('Cannot use process.umask() to change mask (read-only)')
    }
    return process.umask()
  }
  return facade
}

export function copyGlobalProperties(sandbox: Record<string, unknown>, globalObj: any): Record<string, unknown> {
  // Use Object.keys so `instanceof Error` and `instanceof TypeError` keep
  // working inside the extension realm.
  for (const key of Object.keys(globalObj)) {
    const value = sandbox[key]
    if (value === undefined) {
      sandbox[key] = globalObj[key]
    }
  }
  return sandbox
}

View on GitHub (pinned to 50e974d969)

Solutions

  1. Remove the umask(mask) call from the extension.
  2. Compute desired permissions explicitly (fs.chmod / mode flags in fs options) instead of relying on umask.
  3. Only use process.umask() with no args if you need to read the current mask.
  4. Patch/upgrade the offending dependency that mutates umask.

Example fix

// before
process.umask(0o077)
fs.writeFileSync(p, data)
// after
fs.writeFileSync(p, data, { mode: 0o600 })
Defensive patterns

Strategy: try-catch

Validate before calling

// guard in extension code before writing files:
const mode = 0o644 // set explicit modes instead of changing umask
fs.writeFileSync(p, data, { mode })

Try / catch

try { process.umask(mask) } catch { /* sandbox: umask read-only; use explicit fs modes instead */ }

Prevention

When it happens

Trigger: Extension code calls process.umask(0o022) (common in file-creation utilities or build scripts) inside the sandboxed runtime.

Common situations: Libraries that set a restrictive umask before writing files (e.g. tmp-writing helpers); code copied from CLI tools assuming full Node process access.

Related errors


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