{"record":{"id":"bf65833a917636e5","repo":"neoclide/coc.nvim","slug":"cannot-use-process-umask-to-change-mask-read-on","errorCode":null,"errorMessage":"Cannot use process.umask() to change mask (read-only)","messagePattern":"Cannot use process\\.umask\\(\\) to change mask \\(read-only\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/extension/loader.ts","lineNumber":140,"sourceCode":"}\n\n/**\n * Process facade exposed to extensions as the `process` global and returned\n * by `require('process')` / `require('node:process')`.\n */\nexport function createProcessFacade(): NodeJS.Process {\n  const facade: any = new (process as any).constructor()\n  for (let key of Reflect.ownKeys(process)) {\n    if (typeof key === 'string' && key.startsWith('_')) continue\n    facade[key] = process[key]\n  }\n  REMOVED_GLOBALS.forEach(name => {\n    facade[name] = removedGlobalStub(name)\n  })\n  facade['chdir'] = () => {}\n  facade['umask'] = (mask?: number) => {\n    if (typeof mask !== 'undefined') {\n      throw new Error('Cannot use process.umask() to change mask (read-only)')\n    }\n    return process.umask()\n  }\n  return facade\n}\n\nexport function copyGlobalProperties(sandbox: Record<string, unknown>, globalObj: any): Record<string, unknown> {\n  // Use Object.keys so `instanceof Error` and `instanceof TypeError` keep\n  // working inside the extension realm.\n  for (const key of Object.keys(globalObj)) {\n    const value = sandbox[key]\n    if (value === undefined) {\n      sandbox[key] = globalObj[key]\n    }\n  }\n  return sandbox\n}\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/extension/loader.ts#L122-L158","documentation":" 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.","triggerScenarios":"Extension code calls process.umask(0o022) (common in file-creation utilities or build scripts) inside the sandboxed runtime.","commonSituations":"Libraries that set a restrictive umask before writing files (e.g. tmp-writing helpers); code copied from CLI tools assuming full Node process access.","solutions":["Remove the umask(mask) call from the extension.","Compute desired permissions explicitly (fs.chmod / mode flags in fs options) instead of relying on umask.","Only use process.umask() with no args if you need to read the current mask.","Patch/upgrade the offending dependency that mutates umask."],"exampleFix":"// before\nprocess.umask(0o077)\nfs.writeFileSync(p, data)\n// after\nfs.writeFileSync(p, data, { mode: 0o600 })","handlingStrategy":"try-catch","validationCode":"// guard in extension code before writing files:\nconst mode = 0o644 // set explicit modes instead of changing umask\nfs.writeFileSync(p, data, { mode })","typeGuard":null,"tryCatchPattern":"try { process.umask(mask) } catch { /* sandbox: umask read-only; use explicit fs modes instead */ }","preventionTips":["Never mutate umask from extension code","Pass explicit mode flags to fs write calls","Replace dependencies that call process.umask(n) with configurable-mode alternatives"],"tags":["sandbox","security","process-global","permissions"],"backgroundTag":"process-umask-read-only","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}