wavetermdev/waveterm · error

unsupported or invalid signal %q

Error message

unsupported or invalid signal %q

What it means

SendSignalByName looks up an os.Signal via ParseSignal; when the supplied name is not a recognized signal it returns nil and this error is raised. It is a strict validation of user-supplied signal names before any process interaction. The requested pid was never contacted.

Source

Thrown at pkg/util/unixutil/unixutil_unix.go:87

	return syscall.Kill(pid, syscall.SIGHUP)
}

func IsPidRunning(pid int) bool {
	if pid <= 0 {
		return false
	}
	err := syscall.Kill(pid, 0)
	// EPERM means no permission, but it exists (ESRCH is not found)
	if err == nil || err == syscall.EPERM {
		return true
	}
	return false
}

func SendSignalByName(pid int, sigName string) error {
	sig := ParseSignal(sigName)
	if sig == nil {
		return fmt.Errorf("unsupported or invalid signal %q", sigName)
	}
	p, err := os.FindProcess(pid)
	if err != nil {
		return fmt.Errorf("process %d not found: %w", pid, err)
	}
	return p.Signal(sig)
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Validate the signal name with the same parser before calling: check unixutil.ParseSignal(sigName) != nil, or normalize against a known signal list
  2. Normalize input: accept forms with or without the "SIG" prefix, trim whitespace, and upper-case before passing through
  3. For numeric input, map integers to signal names first and reject out-of-range values
  4. Return the list of supported signal names in the error/help text so the user can correct the input

Example fix

// before
err := unixutil.SendSignalByName(pid, "kill") // error: unsupported or invalid signal "kill"
// after
name := strings.ToUpper(strings.TrimSpace(input))
if !strings.HasPrefix(name, "SIG") {
    name = "SIG" + name
}
if unixutil.ParseSignal(name) == nil {
    return fmt.Errorf("unsupported signal %q; valid: SIGTERM, SIGKILL, SIGHUP, ...", input)
}
err := unixutil.SendSignalByName(pid, name)
Defensive patterns

Strategy: validation

Validate before calling

func validSignal(name string) bool {
    n := strings.ToUpper(strings.TrimSpace(name))
    if !strings.HasPrefix(n, "SIG") { n = "SIG" + n }
    return unixutil.ParseSignal(n) != nil
}

Try / catch

if err := unixutil.SendSignalByName(pid, sig); err != nil {
    if strings.HasPrefix(err.Error(), "unsupported or invalid signal") {
        // show supported signals to the user, do not retry
    }
}

Prevention

When it happens

Trigger: Calling SendSignalByName(pid, "SIGKILL ") with trailing whitespace, an alias like "kill" or "9", a lowercase name on a platform whose parser is case-sensitive, or any name ParseSignal does not know (e.g. "SIGUSR3"). Typically invoked via RemoteProcessSignalCommand with user-typed input.

Common situations: Remote command handlers passing raw CLI text or JSON fields straight into the signal API; users typing "stop" or "terminate" instead of a real signal name; scripts omitting the SIG prefix inconsistently.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/9a6139966d001c08. Report an issue: GitHub.