denoland/deno · error · TypeError
ERR_WORKER_UNSUPPORTED_OPERATION
ERR_WORKER_UNSUPPORTED_OPERATION
Error message
Setting process.umask() is not supported in workers
What it means
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.
Source
Thrown at ext/node/polyfills/process.ts:237
// terminate_execution(). Unlike Node.js where reallyExit is a C++ binding
// and a single nop() call suffices to trigger the stack guard check, in Deno
// reallyExit goes through JS frames (Deno.exit -> exitHandler -> workerClose
// -> op), so we need a loop back-edge for V8 to reliably detect the pending
// termination and throw an uncatchable TerminationException.
// On the main thread reallyExit() normally never returns, but users can
// override it (test-process-really-exit.js), so only spin in workers.
// ref: https://github.com/nodejs/node/blob/9cc7fcc26d/lib/internal/process/per_thread.js#L243-L251
if (internals.__isWorkerThread) {
// deno-lint-ignore no-empty
for (;;) {}
}
};
/** https://nodejs.org/api/process.html#processumaskmask */
export function umask(mask?: number | string): number {
if (mask !== undefined) {
if (internals.__isWorkerThread) {
throw new ERR_WORKER_UNSUPPORTED_OPERATION("Setting process.umask()");
}
mask = parseFileMode(mask, "mask");
return op_fs_umask(mask & 0o777);
}
// Note: reading the umask without setting has an inherent race condition
// (two syscalls: set to 0 then restore). Node.js has the same issue and
// has deprecated process.umask() with no arguments. In Deno, the underlying
// op requires allow-sys=umask for both reading and setting.
return op_fs_umask(null);
}
export const abort = () => {
op_process_abort();
};
function addReadOnlyProcessAlias(
name: string,
option: string,View on GitHub (pinned to 9ad36f7a2c)
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
Example fix
// before (runs inside a Worker)
process.umask(0o022); // throws ERR_WORKER_UNSUPPORTED_OPERATION
// after
const { isMainThread } = require("node:worker_threads");
if (isMainThread) process.umask(0o022);
// workers inherit the process-wide umask set by the main thread Defensive patterns
Strategy: validation
Validate before calling
const { isMainThread } = require("node:worker_threads");
if (isMainThread) {
process.umask(mask & 0o777); // set once, before spawning workers
} else {
process.umask(); // read-only in workers
} Type guard
const canSetUmask = () => require("node:worker_threads").isMainThread; Try / catch
try {
process.umask(0o022);
} catch (err) {
if (err.code === "ERR_WORKER_UNSUPPORTED_OPERATION") {
// skip — workers inherit the main thread's umask
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ERR_INVALID_URL
- ERR_INVALID_ARG_VALUE
- ERR_UNKNOWN_SIGNAL
- Empty filepath.
- resolve hook must return { shortCircuit: true } or call next
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/e2ca529d97c50fea.
Report an issue: GitHub.