wavetermdev/waveterm · error

process %d not found: %w

Error message

process %d not found: %w

What it means

After the signal name parses, SendSignalByName calls os.FindProcess(pid); if the OS lookup fails, the pid is wrapped in this error with the underlying cause (%w). On Unix FindProcess only fails for invalid/egative pids or system errors — it does not verify the process actually exists (that surfaces later from p.Signal).

Source

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

	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. Check the pid is a positive integer before calling SendSignalByName; reject 0 and negatives at the command boundary
  2. Re-resolve the process (list processes / check IsPidRunning) to obtain a fresh valid pid before signaling
  3. Inspect errors.Is/As on the wrapped cause (e.g. os.ErrProcessDone, syscall errors) to give a precise user-facing message
  4. Distinguish "not found" from "signal delivery failed" in your API so users know whether to retry or fix input

Example fix

// before
err := unixutil.SendSignalByName(0, "SIGTERM") // process 0 not found: invalid argument
// after
if pid <= 0 {
    return fmt.Errorf("invalid pid %d: must be a positive process id", pid)
}
if !unixutil.IsPidRunning(pid) {
    return fmt.Errorf("process %d is not running", pid)
}
err := unixutil.SendSignalByName(pid, "SIGTERM")
Defensive patterns

Strategy: validation

Validate before calling

if pid <= 0 {
    return fmt.Errorf("invalid pid %d", pid)
}
if !unixutil.IsPidRunning(pid) {
    return fmt.Errorf("process %d is not running", pid)
}

Try / catch

if err := unixutil.SendSignalByName(pid, sig); err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) || strings.Contains(err.Error(), "not found") {
        // re-resolve pid before retrying
    }
}

Prevention

When it happens

Trigger: Passing pid <= 0 (e.g. an uninitialized or zero-valued pid from a lookup that failed upstream), or a pid exceeding platform pid limits. The wrapped error from os.FindProcess carries the OS-specific reason.

Common situations: Remote signal commands where the client sends a stale or never-resolved pid of 0/-1; integer coercion bugs turning "1234" into 0; pid from a config file that no longer matches any process.

Related errors


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