{"record":{"id":"a614e004915166fe","repo":"denoland/deno","slug":"err-unknown-signal-a614e0","errorCode":"ERR_UNKNOWN_SIGNAL","errorMessage":"Unknown signal: ${signal}","messagePattern":"Unknown signal: (.+?)","errorType":"validation","errorClass":"ERR_UNKNOWN_SIGNAL","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/util.mjs","lineNumber":182,"sourceCode":"    if (ObjectHasOwn(os.signals, key)) {\n      signalsToNamesMapping[os.signals[key]] = key;\n    }\n  }\n\n  return signalsToNamesMapping;\n}\n\nfunction convertToValidSignal(signal) {\n  if (typeof signal === \"number\" && getSignalsToNamesMapping()[signal]) {\n    return signal;\n  }\n\n  if (typeof signal === \"string\") {\n    const signalName = os.signals[StringPrototypeToUpperCase(signal)];\n    if (signalName) return signalName;\n  }\n\n  throw new ERR_UNKNOWN_SIGNAL(signal);\n}\n\nconst codesWarned = new SafeSet();\n\nconst experimentalWarnings = new SafeSet();\n\nfunction emitExperimentalWarning(feature, messagePrefix, code, ctor) {\n  if (SetPrototypeHas(experimentalWarnings, feature)) return;\n  SetPrototypeAdd(experimentalWarnings, feature);\n  let msg =\n    `${feature} is an experimental feature and might change at any time`;\n  if (messagePrefix) {\n    msg = messagePrefix + msg;\n  }\n  globalThis.process.emitWarning(msg, \"ExperimentalWarning\", code, ctor);\n}\n\nconst pendingCodesWarned = new SafeSet();","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/util.mjs#L164-L200","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nspawn('sleep', ['5'], { killSignal: 'SIGKILLL' });\n\n// after\nspawn('sleep', ['5'], { killSignal: 'SIGKILL' });","handlingStrategy":"validation","validationCode":"import * as os from 'node:os';\n\nconst KNOWN_SIGNALS = new Set(Object.keys(os.constants.signals));\n\nfunction validKillSignal(sig: string): string {\n  const s = sig.toUpperCase();\n  if (KNOWN_SIGNALS.has(s)) return s;\n  return 'SIGTERM';\n}\n\nspawn(cmd, args, { killSignal: validKillSignal(cfg.killSignal) });","typeGuard":"const isKnownSignal = (sig: string): boolean =>\n  sig.toUpperCase() in os.constants.signals;","tryCatchPattern":"try {\n  child = spawn(cmd, args, { killSignal: sig });\n} catch (err) {\n  if (err?.code === 'ERR_UNKNOWN_SIGNAL') child = spawn(cmd, args, { killSignal: 'SIGTERM' });\n  else throw err;\n}","preventionTips":["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"],"tags":["signals","child-process","node-compat","deno","process"],"backgroundTag":"unknown-signal","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}