{"record":{"id":"ad0b5ca94e327727","repo":"pranshuparmar/witr","slug":"invalid-pid-d-ad0b5c","errorCode":null,"errorMessage":"invalid pid %d","messagePattern":"invalid pid (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/proc/process_freebsd.go","lineNumber":21,"sourceCode":"package proc\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pranshuparmar/witr/pkg/model\"\n)\n\nfunc ReadProcess(pid int) (model.Process, error) {\n\t// Reject PID 0 (and negatives): on FreeBSD `ps -p 0` returns the kernel\n\t// swapper, which is not a real userland target. Matches the other platforms.\n\tif pid <= 0 {\n\t\treturn model.Process{}, fmt.Errorf(\"invalid pid %d\", pid)\n\t}\n\tpidStr := strconv.Itoa(pid)\n\n\t// Format: pid(0) ppid(1) uid(2) jid(3) state(4) pcpu(5) rss(6) lstart(7-11) args(12+)\n\t// comm is excluded because it can contain spaces, which breaks strings.Fields parsing.\n\t// The display name is derived from args instead.\n\tcmd := exec.Command(\"ps\", \"-p\", pidStr,\n\t\t\"-o\", \"pid=\", \"-o\", \"ppid=\", \"-o\", \"uid=\", \"-o\", \"jid=\",\n\t\t\"-o\", \"state=\", \"-o\", \"pcpu=\", \"-o\", \"rss=\",\n\t\t\"-o\", \"lstart=\", \"-o\", \"args=\")\n\tcmd.Env = buildEnvForPS()\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\treturn model.Process{}, fmt.Errorf(\"process %d not found: %w\", pid, err)\n\t}\n\n\tline := strings.TrimSpace(string(out))\n\tif line == \"\" {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/pranshuparmar/witr/blob/dc4fa1da82d3e266fcbd928641b4f30b3077c64f/internal/proc/process_freebsd.go#L3-L39","documentation":"On FreeBSD, ReadProcess validates the PID before invoking ps: pid <= 0 is rejected because `ps -p 0` on FreeBSD returns the kernel swapper, which is not a real userland target, matching the guard on other platforms. It is input validation, not a runtime failure.","triggerScenarios":"Calling ReadProcess (directly or via pidIdentityChanged) with pid <= 0 — typically an uninitialized/zero PID or a sentinel meaning 'no parent found'.","commonSituations":"Passing 0 for a not-yet-discovered parent PID; zero-valued struct fields flowing into the lookup.","solutions":["Fix the caller that produced 0/negative PID.","Skip the call when pid <= 0 and treat it as 'unknown process'.","Validate PID > 0 before calling witr APIs."],"exampleFix":"// before\nproc, err := proc.ReadProcess(pid) // pid == 0\n// after\nif pid > 0 {\n    proc, err = proc.ReadProcess(pid)\n}","handlingStrategy":"validation","validationCode":"if pid <= 0 {\n    return fmt.Errorf(\"cannot read process: pid %d is invalid\", pid)\n}","typeGuard":null,"tryCatchPattern":"proc, err := proc.ReadProcess(pid)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid pid\") {\n        // input bug: do not retry; fix the PID source\n    }\n}","preventionTips":["Validate PID > 0 at the boundary of your own API","Use nil/flags instead of 0 to represent 'no process'","Guard against zero-valued structs leaking into lookups"],"tags":["freebsd","input-validation","pid"],"backgroundTag":"invalid-pid","analyzedSha":"dc4fa1da82d3e266fcbd928641b4f30b3077c64f","analyzedAt":"2026-09-01T12:17:08.767Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}