gastownhall/beads · error

gh run list failed: %s

Error message

gh run list failed: %s

What it means

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.

Source

Thrown at cmd/bd/gate_discover.go:468

		"run", "list",
		"--json", "databaseId,displayTitle,headBranch,headSha,name,status,conclusion,createdAt,updatedAt,workflowName,url",
		"--limit", strconv.Itoa(limit),
	}

	if branch != "" {
		args = append(args, "--branch", branch)
	}
	if repo != "" {
		args = append(args, "--repo", repo)
	}
	if workflow != "" {
		args = append(args, "--workflow", workflow)
	}

	output, stderr, err := runGH(args...)
	if err != nil {
		if len(stderr) > 0 {
			return nil, fmt.Errorf("gh run list failed: %s", string(stderr))
		}
		return nil, fmt.Errorf("gh run list: %w", err)
	}

	var runs []GHWorkflowRun
	if err := json.Unmarshal(output, &runs); err != nil {
		return nil, fmt.Errorf("parse gh output: %w", err)
	}

	return runs, nil
}

// matchGateToRun finds the best matching run for a gate using heuristics.
// If the gate has a workflow name hint in AwaitID, only runs matching that workflow are considered.
//
// foreignRepo must be true when runs were queried from a repo other than the
// current one (SF1: a gate whose metadata.repo targets another repository).
// In that case the local commit SHA and branch name are meaningless - they

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the stderr text in the error — it names the concrete gh cause
  2. Run `gh auth status`; if expired, `gh auth login` (or `gh auth refresh`)
  3. For foreign-repo gates, verify the metadata.repo is a real, accessible repo: `gh repo view OWNER/REPO`
  4. Test the exact command manually: `gh run list --json databaseId --limit 20 [--repo ... --workflow ...]`
  5. If rate-limited, wait for the quota window or use a token with a higher rate limit

Example fix

// before
$ bd gate discover
Error: gh run list failed: exit status 4: GraphQL: Could not resolve to a Repository (typo'd repo)
// after
$ bd update bd-123 --metadata '{"repo":"gastownhall/beads"}'
$ bd gate discover
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight both auth and repo access before discovery
if err := exec.Command("gh", "auth", "status").Run(); err != nil {
  return fmt.Errorf("gh not authenticated: run `gh auth login`")
}
if repo != "" {
  if err := exec.Command("gh", "repo", "view", repo).Run(); err != nil {
    return fmt.Errorf("cannot access repo %q via gh", repo)
  }
}

Try / catch

if _, err := queryGitHubRunsInRepo(branch, limit, repo, workflow); err != nil {
  var ghFail *GHRunListError
  if errors.As(err, &ghFail) || strings.HasPrefix(err.Error(), "gh run list failed:") {
    // stderr carries gh's own diagnosis: check auth (`gh auth status`),
    // repo existence (`gh repo view`), and rate limits before retrying
    return err
  }
  return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/a2a046d4c482e003. Report an issue: GitHub.