gastownhall/beads · error

failed to query workflow runs: %w

Error message

failed to query workflow runs: %w

What it means

Wraps any failure from `gh run list` when resolving a gate's workflow-name hint to a numeric run ID. It is raised in discoverRunIDByWorkflowNameInRepoWithRunner (cmd/bd/gate.go:997) and bundles the underlying cause (gh CLI failure, stderr from GitHub, or JSON parse error) via %w.

Source

Thrown at cmd/bd/gate.go:997

func discoverRunIDByWorkflowName(workflowHint string) (string, error) {
	return discoverRunIDByWorkflowNameInRepo(workflowHint, "")
}

func discoverRunIDByWorkflowNameInRepo(workflowHint, repo string) (string, error) {
	return discoverRunIDByWorkflowNameInRepoWithRunner(workflowHint, repo, runGHCommand)
}

// discoverRunIDByWorkflowNameInRepoWithRunner is the runner-injectable form of
// discoverRunIDByWorkflowNameInRepo. checkGHRunWithRunner's cross-repo branch
// must call this (not discoverRunIDByWorkflowNameInRepo directly) so the same
// injected ghCommandRunner seam used everywhere else in the gh:run/gh:pr
// checks also covers cross-repo discovery, keeping that path unit-testable
// without a live `gh` CLI (standards note on the SF1 review).
func discoverRunIDByWorkflowNameInRepoWithRunner(workflowHint, repo string, runGH ghCommandRunner) (string, error) {
	// Query GitHub directly for this workflow (efficient, avoids limit issues)
	runs, err := queryGitHubRunsForWorkflowInRepoWithRunner(workflowHint, 5, repo, runGH)
	if err != nil {
		return "", fmt.Errorf("failed to query workflow runs: %w", err)
	}

	if len(runs) == 0 {
		return "", fmt.Errorf("no runs found for workflow '%s'", workflowHint)
	}

	// Take the most recent run (gh returns newest-first)
	// This is deterministic: "most recent" is a total ordering by creation time
	return fmt.Sprintf("%d", runs[0].DatabaseID), nil
}

// checkGHRun checks a GitHub Actions workflow run gate.
// When persistAwaitID is nil, workflow-name discovery stays in-memory only.
func checkGHRun(gate *types.Issue, persistAwaitID func(gateID, runID string) error) (resolved, escalated bool, reason string, err error) {
	return checkGHRunWithRunner(gate, persistAwaitID, runGHCommand)
}

func checkGHRunWithRunner(gate *types.Issue, persistAwaitID func(gateID, runID string) error, runGH ghCommandRunner) (resolved, escalated bool, reason string, err error) {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run `gh run list --workflow=<name> --repo <owner/repo>` manually to see the real gh error wrapped underneath
  2. Re-authenticate with `gh auth login` or refresh GH_TOKEN
  3. Verify the workflow name matches the workflow file name exactly in the target repo
  4. Check the repo slug in the gate metadata points at an accessible repository

Example fix

// before
discoveredID, discoverErr = discoverRunIDByWorkflowNameInRepoWithRunner(gate.AwaitID, repo, runGH)
// after
if discoveredID, discoverErr = discoverRunIDByWorkflowNameInRepoWithRunner(gate.AwaitID, repo, runGH); discoverErr != nil {
    log.Printf("gate %s: hint %s failed: %v", gate.ID, gate.AwaitID, discoverErr) // inspect wrapped cause
}
Defensive patterns

Strategy: retry

Validate before calling

gh auth status && gh run list --workflow=<hint> --repo <owner/repo> --limit 1

Try / catch

if resolved, esc, reason, err := checkGHRun(gate); err != nil && strings.Contains(err.Error(), "failed to query workflow runs") {
    // log wrapped cause: fmt.Errorf("%w", err); retry after backoff
}

Prevention

When it happens

Trigger: A gh:run gate whose await_id is a non-numeric workflow name hint is evaluated and queryGitHubRunsForWorkflowInRepoWithRunner fails: gh returns non-zero (auth error, network failure, unknown workflow) or its JSON output cannot be parsed.

Common situations: gh not authenticated (GH_TOKEN expired), wrong --repo slug, workflow file renamed/deleted so the name no longer matches, offline CI runner, gh CLI version emitting unexpected JSON.

Related errors


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