gastownhall/beads · error
gh CLI not found: install from https://cli.github.com
Error message
gh CLI not found: install from https://cli.github.com
What it means
queryGitHubRunsForWorkflowInRepo shells out to the GitHub `gh` CLI; before doing so it runs exec.LookPath("gh"). If no `gh` executable exists on PATH, gate checks that query workflow runs cannot proceed and this error is returned, pointing to the official install page.
Source
Thrown at cmd/bd/gate.go:945
if repo == "" {
return nil, nil
}
metadata, err := json.Marshal(map[string]string{"repo": repo})
if err != nil {
return nil, err
}
return metadata, nil
}
// queryGitHubRunsForWorkflow queries recent runs for a specific workflow using gh CLI.
// Returns runs sorted newest-first (GitHub API default).
func queryGitHubRunsForWorkflow(workflow string, limit int) ([]GHWorkflowRun, error) {
return queryGitHubRunsForWorkflowInRepo(workflow, limit, "")
}
func queryGitHubRunsForWorkflowInRepo(workflow string, limit int, repo string) ([]GHWorkflowRun, error) {
if _, err := exec.LookPath("gh"); err != nil {
return nil, fmt.Errorf("gh CLI not found: install from https://cli.github.com")
}
return queryGitHubRunsForWorkflowInRepoWithRunner(workflow, limit, repo, runGHCommand)
}
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 {View on GitHub (pinned to 71377f2769)
Solutions
- Install gh CLI (https://cli.github.com): e.g. `brew install gh` or apt/dnf per the docs.
- Ensure the binary is on PATH for the user running bd: verify with `which gh`; adjust PATH in CI or service environments.
- In containers, add gh installation to the image build instead of runtime.
- Alternatively, provide a runner injection (ghCommandRunner) in tests/custom tooling so a real gh lookup is not required.
Example fix
// before (CI step without gh)
- run: bd doctor
// after
- run: |
type -p gh >/dev/null || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && sudo apt install gh)
- run: bd doctor Defensive patterns
Strategy: fallback
Validate before calling
if _, err := exec.LookPath("gh"); err != nil {
// skip GH gate checks or print install guidance instead of failing hard
return nil // or fmt.Errorf("gh required for gate checks: %w", err)
} Try / catch
runs, err := queryGitHubRunsForWorkflow("ci.yml", 5)
if err != nil {
if strings.Contains(err.Error(), "gh CLI not found") {
log.Printf("skipping GitHub gate checks: %v", err)
return nil
}
return err
} Prevention
- Install gh in CI images at build time (bake into Dockerfile).
- Add a doctor-style preflight that checks `gh --version` before workflows needing it.
- Ensure service users' PATH includes the gh install location (/usr/local/bin, /opt/homebrew/bin).
When it happens
Trigger: Any flow calling queryGitHubRunsForWorkflow / queryGitHubRunsForWorkflowInRepo (e.g. CI-gate checks matching beads gates to GH Actions runs) on a machine where gh is not installed or not on PATH.
Common situations: Fresh CI containers without gh installed; PATH differences between user shell and service accounts; gh installed via GUI but not symlinked into PATH; restricted environments (minimal Docker images).
Related errors
- gh CLI not found: install from https://cli.github.com
- gh run list: %w
- gh run list --workflow=%s failed: %s
- gh run list: %w
- parse gh output: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e50fefa920aa138c.
Report an issue: GitHub.