denoland/deno · error · ERR_WORKER_INVALID_EXEC_ARGV
ERR_WORKER_INVALID_EXEC_ARGV
ERR_WORKER_INVALID_EXEC_ARGV
Error message
Initiated Worker with invalid execArgv flags: ${invalidFlags} What it means
ERR_WORKER_INVALID_EXEC_ARGV is thrown by the Worker constructor when options.execArgv contains flags that are not recognized Node environment flags, or are valid process-wide flags that are forbidden inside workers because they mutate per-process state. Deno's polyfill checks each leading-'-' token against process.allowedNodeEnvironmentFlags plus a disallowed set (--title, --redirect-warnings, --report-*, tracing/diagnostic flags); V8 profiling flags (--cpu-prof*, --heap-prof*) are accepted and silently ignored.
Source
Thrown at ext/node/polyfills/worker_threads.ts:330
continue;
}
const eqIdx = StringPrototypeIndexOf(flag, "=");
const flagName = eqIdx === -1
? flag
: StringPrototypeSlice(flag, 0, eqIdx);
if (workerSilentlyIgnoredFlags.has(flagName)) {
continue;
}
if (!lazyProcess().default.allowedNodeEnvironmentFlags.has(flag)) {
invalidFlags[invalidFlags.length] = flag;
continue;
}
if (workerDisallowedFlags.has(flagName)) {
invalidFlags[invalidFlags.length] = flag;
}
}
if (invalidFlags.length > 0) {
throw new ERR_WORKER_INVALID_EXEC_ARGV(invalidFlags);
}
}
}
if (options?.env) {
const nodeOptions = options.env.NODE_OPTIONS;
if (typeof nodeOptions === "string" && nodeOptions.length > 0) {
// Parse NODE_OPTIONS and validate each flag
const parts = StringPrototypeSplit(
StringPrototypeTrim(nodeOptions),
new SafeRegExp("\\s+"),
);
let hasInvalid = false;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (StringPrototypeStartsWith(part, "-")) {
const eqIdx = StringPrototypeIndexOf(part, "=");
const partName = eqIdx === -1View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Filter execArgv to flags you know are allowed before constructing the Worker (see validationCode).
- Remove worker-forbidden flags from the list: --title, --redirect-warnings, --trace-event-file-pattern, --trace-event-categories, --trace-events-enabled, --diagnostic-dir, --report-signal, --report-filename, --report-dir, --report-directory, --report-compact, --report-on-signal, --report-on-fatalerror, --report-uncaught-exception.
- Fix or unset a bad NODE_OPTIONS in the environment (`env | grep NODE_OPTIONS`) when the error comes from options.env rather than execArgv.
Example fix
// before
new Worker(filename, { execArgv: process.execArgv }); // may carry --title etc.
// after
const workerForbidden = new Set(['--title', '--redirect-warnings', '--diagnostic-dir',
'--report-signal', '--report-filename', '--report-dir', '--report-directory',
'--report-compact', '--report-on-signal', '--report-on-fatalerror',
'--report-uncaught-exception', '--trace-event-file-pattern',
'--trace-event-categories', '--trace-events-enabled']);
const execArgv = process.execArgv.filter((f) => {
const name = f.split('=')[0];
return !workerForbidden.has(name) && process.allowedNodeEnvironmentFlags.has(name);
});
new Worker(filename, { execArgv }); Defensive patterns
Strategy: validation
Validate before calling
const WORKER_FORBIDDEN_FLAGS = new Set([
'--title', '--redirect-warnings', '--trace-event-file-pattern',
'--trace-event-categories', '--trace-events-enabled', '--diagnostic-dir',
'--report-signal', '--report-filename', '--report-dir', '--report-directory',
'--report-compact', '--report-on-signal', '--report-on-fatalerror',
'--report-uncaught-exception',
]);
function sanitizeExecArgv(flags: string[]): string[] {
return flags.filter((flag) => {
if (!flag.startsWith('-')) return true; // flag arguments pass through
const name = flag.split('=')[0];
if (WORKER_FORBIDDEN_FLAGS.has(name)) return false;
return process.allowedNodeEnvironmentFlags.has(name);
});
}
new Worker(filename, { execArgv: sanitizeExecArgv(process.execArgv) }); Type guard
function isWorkerSafeFlag(flag: string): boolean {
if (!flag.startsWith('-')) return true;
const name = flag.split('=')[0];
if (WORKER_FORBIDDEN_FLAGS.has(name)) return false;
return process.allowedNodeEnvironmentFlags.has(flag);
} Try / catch
try {
worker = new Worker(filename, { execArgv });
} catch (err) {
if ((err as { code?: string }).code === 'ERR_WORKER_INVALID_EXEC_ARGV') {
worker = new Worker(filename, { execArgv: sanitizeExecArgv(execArgv) });
} else {
throw err;
}
} Prevention
- Do not forward process.execArgv into workers blindly; filter it first.
- Keep NODE_OPTIONS clean in deploy environments; the same validation applies to options.env.NODE_OPTIONS.
- Pass only flags you have verified against process.allowedNodeEnvironmentFlags, minus the report/tracing/title group.
When it happens
Trigger: `new Worker(file, { execArgv: ['--title=main'] })`, `execArgv: ['--max-old-space-size=4096', '--unsupported-flag']`, or flags forwarded from the parent that include worker-forbidden entries; the same validation runs against flags found in options.env.NODE_OPTIONS.
Common situations: Forwarding `process.execArgv` into every worker unconditionally; CI or prod harnesses that inject report/tracing flags globally; scripts assuming Deno rejects nothing in execArgv; misconfigured NODE_OPTIONS in the environment.
Related errors
- ERR_INSPECTOR_NOT_WORKER
- ERR_WORKER_UNSUPPORTED_OPERATION
- ERR_INVALID_URL_SCHEME
- ERR_INVALID_ARG_TYPE
- ERR_CONSTRUCT_CALL_REQUIRED
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/e0e784fcfe7e0742.
Report an issue: GitHub.