{"record":{"id":"473b456b94f60bdc","repo":"AdguardTeam/AdGuardHome","slug":"ps-finished-with-code-d","errorCode":null,"errorMessage":"ps finished with code %d","messagePattern":"ps finished with code (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghos/os.go","lineNumber":111,"sourceCode":"\tvar instNum int\n\tpid, instNum, err = parsePSOutput(&stdoutBuf, command, except)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tswitch instNum {\n\tcase 0:\n\t\t// TODO(e.burkov):  Use constant error.\n\t\treturn 0, fmt.Errorf(\"no %s instances found\", command)\n\tcase 1:\n\t\t// Go on.\n\tdefault:\n\t\tl.WarnContext(ctx, \"instances found\", \"num\", instNum, \"command\", command)\n\t}\n\n\tif runErr != nil {\n\t\tif code, ok := executil.ExitCodeFromError(runErr); ok {\n\t\t\treturn 0, fmt.Errorf(\"ps finished with code %d\", code)\n\t\t}\n\n\t\treturn 0, fmt.Errorf(\"executing the command: %w\", runErr)\n\t}\n\n\treturn pid, nil\n}\n\n// parsePSOutput scans the output of ps searching the largest PID of the process\n// associated with cmdName ignoring PIDs from ignore.  A valid line from r\n// should look like these:\n//\n//\t 123 ./example-cmd\n//\t1230 some/base/path/example-cmd\n//\t3210 example-cmd\nfunc parsePSOutput(r io.Reader, cmdName string, ignore []int) (largest, instNum int, err error) {\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghos/os.go#L93-L129","documentation":"PIDByCommand shells out to ps; if ps exits with a non-zero status code, this error reports that exit code. It means the ps invocation itself failed rather than that the target process was or wasn't found.","triggerScenarios":"The ps child process exits non-zero — ps binary missing (shell returns 127), permission denied reading /proc for other users' processes, unsupported ps flags on busybox/macOS variants, or a hostile environment where ps aborts.","commonSituations":"Minimal Docker images (alpine/distroless) without procps installed; BSD/macOS ps with GNU-only flags; hardened systems hiding /proc entries.","solutions":["Run ps with the same arguments manually to see why it fails","Install procps/psmisc in minimal containers","If ps flags differ per-platform, adjust the executil invocation or patch the flags used","Treat this as an environment problem: fix the host, don't retry the call"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := exec.LookPath(\"ps\"); err != nil { return fmt.Errorf(\"ps unavailable: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var exitErr *exec.ExitError\n    if errors.As(err, &exitErr) || strings.Contains(err.Error(), \"ps finished with code\") {\n        // inspect environment; do not retry blindly\n    }\n}","preventionTips":["Install procps in minimal container images","Smoke-test ps manually in the deployment environment","Avoid running reload flows in stripped-down containers"],"tags":["process","ps","exit-code","subprocess"],"backgroundTag":"subprocess-nonzero-exit","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}