{"record":{"id":"d5b589e1cf1ec2cd","repo":"AdguardTeam/AdGuardHome","slug":"executing-the-command-w","errorCode":null,"errorMessage":"executing the command: %w","messagePattern":"executing the command: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghos/os.go","lineNumber":114,"sourceCode":"\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() {\n\t\tfields := strings.Fields(s.Text())\n\t\tif len(fields) != 2 || path.Base(fields[1]) != cmdName {\n\t\t\tcontinue","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghos/os.go#L96-L132","documentation":"Generic wrapper returned by PIDByCommand when running the ps command fails without a recognizable exit code — i.e. the error couldn't be spawn-related exit status (couldn't start, was killed by signal, or context canceled). The %w preserves the underlying exec error for inspection.","triggerScenarios":"exec.CommandContext fails to start ps (binary not found, PATH issues), the command is killed by a signal (no exit code), or the context passed to PIDByCommand is canceled/expired before ps completes.","commonSituations":"Canceled shutdown contexts during reload; PATH missing /bin/ps in systemd hardening (NoNewPrivileges/RestrictCommands); ps terminated by a supervisor timeout.","solutions":["Inspect the wrapped error with errors.Unwrap to distinguish not-found vs signal vs context.Canceled","Ensure ps exists and is executable in the service's environment (check PATH and systemd restrictions)","Increase or remove the timeout on the context passed to PIDByCommand if it's expiring early"],"exampleFix":"// before\npid, err := aghos.PIDByCommand(ctx, cmd)\n\n// after\npid, err := aghos.PIDByCommand(ctx, cmd)\nif err != nil {\n    if errors.Is(err, context.Canceled) { return }\n    if errors.Is(err, exec.ErrNotFound) { /* install ps */ }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return }\n    if errors.Is(err, exec.ErrNotFound) { /* install ps */ }\n    return err // other exec failure\n}","preventionTips":["Pass a context with adequate timeout","Ensure PATH includes the directory containing ps in service environments","Unwrap and classify the underlying error before retrying"],"tags":["process","ps","exec","context-canceled"],"backgroundTag":"subprocess-exec-failure","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}