{"record":{"id":"e2ca529d97c50fea","repo":"denoland/deno","slug":"err-worker-unsupported-operation","errorCode":"ERR_WORKER_UNSUPPORTED_OPERATION","errorMessage":"Setting process.umask() is not supported in workers","messagePattern":"Setting process\\.umask\\(\\) is not supported in workers","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/process.ts","lineNumber":237,"sourceCode":"  // terminate_execution(). Unlike Node.js where reallyExit is a C++ binding\n  // and a single nop() call suffices to trigger the stack guard check, in Deno\n  // reallyExit goes through JS frames (Deno.exit -> exitHandler -> workerClose\n  // -> op), so we need a loop back-edge for V8 to reliably detect the pending\n  // termination and throw an uncatchable TerminationException.\n  // On the main thread reallyExit() normally never returns, but users can\n  // override it (test-process-really-exit.js), so only spin in workers.\n  // ref: https://github.com/nodejs/node/blob/9cc7fcc26d/lib/internal/process/per_thread.js#L243-L251\n  if (internals.__isWorkerThread) {\n    // deno-lint-ignore no-empty\n    for (;;) {}\n  }\n};\n\n/** https://nodejs.org/api/process.html#processumaskmask */\nexport function umask(mask?: number | string): number {\n  if (mask !== undefined) {\n    if (internals.__isWorkerThread) {\n      throw new ERR_WORKER_UNSUPPORTED_OPERATION(\"Setting process.umask()\");\n    }\n    mask = parseFileMode(mask, \"mask\");\n    return op_fs_umask(mask & 0o777);\n  }\n  // Note: reading the umask without setting has an inherent race condition\n  // (two syscalls: set to 0 then restore). Node.js has the same issue and\n  // has deprecated process.umask() with no arguments. In Deno, the underlying\n  // op requires allow-sys=umask for both reading and setting.\n  return op_fs_umask(null);\n}\n\nexport const abort = () => {\n  op_process_abort();\n};\n\nfunction addReadOnlyProcessAlias(\n  name: string,\n  option: string,","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/process.ts#L219-L255","documentation":"Calling process.umask(mask) — the setting form — inside a worker_threads Worker throws ERR_WORKER_UNSUPPORTED_OPERATION, matching Node's own behavior: umask is process-global, so mutating it from a parallel thread is unsafe. The read-only form, process.umask() with no argument, is allowed in workers; under Deno both forms additionally require the allow-sys=umask permission.","triggerScenarios":"Code inside new Worker(...) calling process.umask(0o022); libraries like node-tmp that set umask at import time being loaded inside a worker pool; test runners (jest workers, etc.) executing setup files per worker.","commonSituations":" npm libraries that set umask on load running under Deno's node compat inside workers; deploy scripts assuming main-thread context; CI matrices where the same entrypoint sometimes runs in a worker.","solutions":["Set the umask once on the main thread before spawning workers","Inside workers, only read: call process.umask() without an argument","Guard the call: if (worker_threads.isMainThread) process.umask(mask)","In Deno, run with --allow-sys=umask so the read path also works"],"exampleFix":"// before (runs inside a Worker)\nprocess.umask(0o022); // throws ERR_WORKER_UNSUPPORTED_OPERATION\n\n// after\nconst { isMainThread } = require(\"node:worker_threads\");\nif (isMainThread) process.umask(0o022);\n// workers inherit the process-wide umask set by the main thread","handlingStrategy":"validation","validationCode":"const { isMainThread } = require(\"node:worker_threads\");\nif (isMainThread) {\n  process.umask(mask & 0o777); // set once, before spawning workers\n} else {\n  process.umask(); // read-only in workers\n}","typeGuard":"const canSetUmask = () => require(\"node:worker_threads\").isMainThread;","tryCatchPattern":"try {\n  process.umask(0o022);\n} catch (err) {\n  if (err.code === \"ERR_WORKER_UNSUPPORTED_OPERATION\") {\n    // skip — workers inherit the main thread's umask\n  } else throw err;\n}","preventionTips":["Set umask once at process startup on the main thread","Treat worker code as read-only for process-global state (umask, cwd, uid/gid)","In Deno, grant --allow-sys=umask if you need to read it"],"tags":["process","umask","worker-threads","node-compat","deno","permissions"],"backgroundTag":"worker-unsupported-operation","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}