denoland/deno · error · ERR_UNKNOWN_SIGNAL
ERR_UNKNOWN_SIGNAL
ERR_UNKNOWN_SIGNAL
Error message
Unknown signal: ${signal} What it means
convertToValidSignal normalizes signal arguments in Deno's node compat layer: a numeric signal must exist in the signals-to-names mapping, a string must resolve (case-insensitively) through os.signals. Anything else throws ERR_UNKNOWN_SIGNAL. Its reachable call site is the killSignal option of child_process.spawn/SpawnSync (ext/node/polyfills/child_process.ts:348); an unknown name, typo, or unsupported-on-this-platform signal number is rejected before the process is spawned.
Source
Thrown at ext/node/polyfills/internal/util.mjs:182
if (ObjectHasOwn(os.signals, key)) {
signalsToNamesMapping[os.signals[key]] = key;
}
}
return signalsToNamesMapping;
}
function convertToValidSignal(signal) {
if (typeof signal === "number" && getSignalsToNamesMapping()[signal]) {
return signal;
}
if (typeof signal === "string") {
const signalName = os.signals[StringPrototypeToUpperCase(signal)];
if (signalName) return signalName;
}
throw new ERR_UNKNOWN_SIGNAL(signal);
}
const codesWarned = new SafeSet();
const experimentalWarnings = new SafeSet();
function emitExperimentalWarning(feature, messagePrefix, code, ctor) {
if (SetPrototypeHas(experimentalWarnings, feature)) return;
SetPrototypeAdd(experimentalWarnings, feature);
let msg =
`${feature} is an experimental feature and might change at any time`;
if (messagePrefix) {
msg = messagePrefix + msg;
}
globalThis.process.emitWarning(msg, "ExperimentalWarning", code, ctor);
}
const pendingCodesWarned = new SafeSet();View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use standard names: killSignal: 'SIGTERM' or 'SIGKILL'
- Pull from the constants: killSignal: os.constants.signals.SIGTERM
- Validate config values against Object.keys(os.constants.signals) before spawning
Example fix
// before
spawn('sleep', ['5'], { killSignal: 'SIGKILLL' });
// after
spawn('sleep', ['5'], { killSignal: 'SIGKILL' }); Defensive patterns
Strategy: validation
Validate before calling
import * as os from 'node:os';
const KNOWN_SIGNALS = new Set(Object.keys(os.constants.signals));
function validKillSignal(sig: string): string {
const s = sig.toUpperCase();
if (KNOWN_SIGNALS.has(s)) return s;
return 'SIGTERM';
}
spawn(cmd, args, { killSignal: validKillSignal(cfg.killSignal) }); Type guard
const isKnownSignal = (sig: string): boolean => sig.toUpperCase() in os.constants.signals;
Try / catch
try {
child = spawn(cmd, args, { killSignal: sig });
} catch (err) {
if (err?.code === 'ERR_UNKNOWN_SIGNAL') child = spawn(cmd, args, { killSignal: 'SIGTERM' });
else throw err;
} Prevention
- Use canonical names: SIGTERM, SIGKILL, SIGINT — or os.constants.signals values
- Validate config-provided signal names against os.constants.signals before spawning
- Do not copy raw signal numbers between platforms
When it happens
Trigger: spawn(cmd, args, { killSignal: 'SIGKILL ' }) with trailing whitespace or 'SIG_STOP'-style typos; killSignal: 'SIGSTOPP'; a numeric signal constant copied from another OS (e.g. signals beyond the platform mapping); killSignal: undefined-typo keys like killSignal: signl.
Common situations: Cross-platform scripts assuming Linux signal names/numbers (SIGKILL=9) that differ on other platforms; typos in config-driven killSignal values; porting C signal numbers directly.
Related errors
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/a614e004915166fe.
Report an issue: GitHub.