{"record":{"id":"a2a046d4c482e003","repo":"gastownhall/beads","slug":"gh-run-list-failed-s","errorCode":null,"errorMessage":"gh run list failed: %s","messagePattern":"gh run list failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/gate_discover.go","lineNumber":468,"sourceCode":"\t\t\"run\", \"list\",\n\t\t\"--json\", \"databaseId,displayTitle,headBranch,headSha,name,status,conclusion,createdAt,updatedAt,workflowName,url\",\n\t\t\"--limit\", strconv.Itoa(limit),\n\t}\n\n\tif branch != \"\" {\n\t\targs = append(args, \"--branch\", branch)\n\t}\n\tif repo != \"\" {\n\t\targs = append(args, \"--repo\", repo)\n\t}\n\tif workflow != \"\" {\n\t\targs = append(args, \"--workflow\", workflow)\n\t}\n\n\toutput, stderr, err := runGH(args...)\n\tif err != nil {\n\t\tif len(stderr) > 0 {\n\t\t\treturn nil, fmt.Errorf(\"gh run list failed: %s\", string(stderr))\n\t\t}\n\t\treturn nil, fmt.Errorf(\"gh run list: %w\", err)\n\t}\n\n\tvar runs []GHWorkflowRun\n\tif err := json.Unmarshal(output, &runs); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse gh output: %w\", err)\n\t}\n\n\treturn runs, nil\n}\n\n// matchGateToRun finds the best matching run for a gate using heuristics.\n// If the gate has a workflow name hint in AwaitID, only runs matching that workflow are considered.\n//\n// foreignRepo must be true when runs were queried from a repo other than the\n// current one (SF1: a gate whose metadata.repo targets another repository).\n// In that case the local commit SHA and branch name are meaningless - they","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/gate_discover.go#L450-L486","documentation":"When the `gh run list` subprocess exits non-zero AND gh wrote output to stderr, bd surfaces that stderr verbatim as \"gh run list failed: <stderr>\". gh prints its human-readable diagnosis (auth failures, unknown repo, unknown workflow, rate limits) on stderr, so this is the most informative gh failure path.","triggerScenarios":"queryGitHubRunsInRepoWithRunner's runGH(args...) returns an error with non-empty stderr: e.g. `gh run list --repo OWNER/REPO` on a repo that doesn't exist or the token can't see, `--workflow <name>` matching no workflow file, expired/missing gh auth token, or API rate limiting.","commonSituations":"Foreign-repo gate with a typo'd metadata.repo (\"cannot find repository\"); gh not authenticated (`gh auth login` never run or token expired); private repo inaccessible to the current gh account; --branch filter with a branch that has no runs combined with a server error; corporate proxy blocking api.github.com.","solutions":["Read the stderr text in the error — it names the concrete gh cause","Run `gh auth status`; if expired, `gh auth login` (or `gh auth refresh`)","For foreign-repo gates, verify the metadata.repo is a real, accessible repo: `gh repo view OWNER/REPO`","Test the exact command manually: `gh run list --json databaseId --limit 20 [--repo ... --workflow ...]`","If rate-limited, wait for the quota window or use a token with a higher rate limit"],"exampleFix":"// before\n$ bd gate discover\nError: gh run list failed: exit status 4: GraphQL: Could not resolve to a Repository (typo'd repo)\n// after\n$ bd update bd-123 --metadata '{\"repo\":\"gastownhall/beads\"}'\n$ bd gate discover","handlingStrategy":"try-catch","validationCode":"// preflight both auth and repo access before discovery\nif err := exec.Command(\"gh\", \"auth\", \"status\").Run(); err != nil {\n  return fmt.Errorf(\"gh not authenticated: run `gh auth login`\")\n}\nif repo != \"\" {\n  if err := exec.Command(\"gh\", \"repo\", \"view\", repo).Run(); err != nil {\n    return fmt.Errorf(\"cannot access repo %q via gh\", repo)\n  }\n}","typeGuard":null,"tryCatchPattern":"if _, err := queryGitHubRunsInRepo(branch, limit, repo, workflow); err != nil {\n  var ghFail *GHRunListError\n  if errors.As(err, &ghFail) || strings.HasPrefix(err.Error(), \"gh run list failed:\") {\n    // stderr carries gh's own diagnosis: check auth (`gh auth status`),\n    // repo existence (`gh repo view`), and rate limits before retrying\n    return err\n  }\n  return err\n}","preventionTips":["Keep gh authenticated: GH_TOKEN in CI, `gh auth login` locally, refresh expiring tokens","Validate foreign-repo metadata.repo values with `gh repo view` when creating cross-repo gates","Use workflow filenames (ci.yml) as AwaitID hints so --workflow never matches nothing","Watch gh rate limits in high-frequency discovery loops and back off"],"tags":["github","cli","authentication","subprocess"],"backgroundTag":"gh-cli-command-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}