{"record":{"id":"3fedecf41e811613","repo":"wavetermdev/waveterm","slug":"process-d-not-found-w","errorCode":null,"errorMessage":"process %d not found: %w","messagePattern":"process (.+?) not found: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/unixutil/unixutil_unix.go","lineNumber":91,"sourceCode":"\tif pid <= 0 {\n\t\treturn false\n\t}\n\terr := syscall.Kill(pid, 0)\n\t// EPERM means no permission, but it exists (ESRCH is not found)\n\tif err == nil || err == syscall.EPERM {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc SendSignalByName(pid int, sigName string) error {\n\tsig := ParseSignal(sigName)\n\tif sig == nil {\n\t\treturn fmt.Errorf(\"unsupported or invalid signal %q\", sigName)\n\t}\n\tp, err := os.FindProcess(pid)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"process %d not found: %w\", pid, err)\n\t}\n\treturn p.Signal(sig)\n}\n","sourceCodeStart":73,"sourceCodeEnd":95,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/util/unixutil/unixutil_unix.go#L73-L95","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the pid is a positive integer before calling SendSignalByName; reject 0 and negatives at the command boundary","Re-resolve the process (list processes / check IsPidRunning) to obtain a fresh valid pid before signaling","Inspect errors.Is/As on the wrapped cause (e.g. os.ErrProcessDone, syscall errors) to give a precise user-facing message","Distinguish \"not found\" from \"signal delivery failed\" in your API so users know whether to retry or fix input"],"exampleFix":"// before\nerr := unixutil.SendSignalByName(0, \"SIGTERM\") // process 0 not found: invalid argument\n// after\nif pid <= 0 {\n    return fmt.Errorf(\"invalid pid %d: must be a positive process id\", pid)\n}\nif !unixutil.IsPidRunning(pid) {\n    return fmt.Errorf(\"process %d is not running\", pid)\n}\nerr := unixutil.SendSignalByName(pid, \"SIGTERM\")","handlingStrategy":"validation","validationCode":"if pid <= 0 {\n    return fmt.Errorf(\"invalid pid %d\", pid)\n}\nif !unixutil.IsPidRunning(pid) {\n    return fmt.Errorf(\"process %d is not running\", pid)\n}","typeGuard":null,"tryCatchPattern":"if err := unixutil.SendSignalByName(pid, sig); err != nil {\n    var pe *os.PathError\n    if errors.As(err, &pe) || strings.Contains(err.Error(), \"not found\") {\n        // re-resolve pid before retrying\n    }\n}","preventionTips":["Reject pid <= 0 at every command boundary","Re-resolve pids freshly instead of caching them across sessions","Use errors.As on the wrapped cause for precise diagnostics"],"tags":["signals","process","pid","go"],"backgroundTag":"process-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}