gastownhall/beads · error

gh run list: %w

Error message

gh run list: %w

What it means

Fallback branch of the same gh subprocess call: if `gh run list` fails but produced NO stderr output, the raw exec error is wrapped as "gh run list: %w". Typically this is a process-level failure (gh not executable, killed by signal, exec format/permission problem) rather than a gh-reported API error.

Source

Thrown at cmd/bd/gate.go:966

}

func queryGitHubRunsForWorkflowInRepoWithRunner(workflow string, limit int, repo string, runGH ghCommandRunner) ([]GHWorkflowRun, error) {
	args := []string{
		"run", "list",
		"--workflow", workflow,
		"--json", "databaseId,name,status,conclusion,createdAt,workflowName",
		"--limit", fmt.Sprintf("%d", limit),
	}
	if repo != "" {
		args = append(args, "--repo", repo)
	}

	output, stderr, err := runGH(args...)
	if err != nil {
		if len(stderr) > 0 {
			return nil, fmt.Errorf("gh run list --workflow=%s failed: %s", workflow, 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
}

// discoverRunIDByWorkflowName queries GitHub for the most recent run of a workflow.
// Returns (runID, error). This is ZFC-compliant: "most recent run" is deterministic.
func discoverRunIDByWorkflowName(workflowHint string) (string, error) {
	return discoverRunIDByWorkflowNameInRepo(workflowHint, "")
}

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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped error text (it follows "gh run list:") for the OS-level cause (permission denied, signal, etc.).
  2. Verify the gh binary: `ls -l $(which gh)` and `gh --version`; reinstall if corrupted or chmod +x if not executable.
  3. If a custom runner is injected (tests/tools), make it return descriptive stderr so future failures surface the gh message instead.
  4. Re-run the failing bd command after fixing the environment.

Example fix

// before (custom runner)
return nil, nil, errors.New("simulated")
// after
return nil, []byte("injected failure"), errors.New("simulated gh failure")
Defensive patterns

Strategy: try-catch

Validate before calling

// verify gh binary health before calls
if out, err := exec.Command("gh", "--version").Output(); err != nil || len(out) == 0 {
    return errors.New("gh binary is not executable or broken")
}

Try / catch

runs, err := queryGitHubRunsForWorkflowInRepo("ci.yml", 5, repo)
if err != nil {
    if strings.HasPrefix(err.Error(), "gh run list: ") {
        return fmt.Errorf("gh process-level failure (binary/permissions/signal): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: runGH invoked but the process fails without writing stderr — e.g. permission denied on the gh binary, SIGKILL/OOM, a test runner replacing ghCommandRunner and returning an error with empty stderr, or stdout/stderr pipe misconfiguration.

Common situations: Non-executable or corrupted gh binary after a partial upgrade; container seccomp/sandbox blocking exec; custom ghCommandRunner implementations in tests returning bare errors.

Related errors


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