gastownhall/beads · error

repo %q must use OWNER/REPO or HOST/OWNER/REPO

Error message

repo %q must use OWNER/REPO or HOST/OWNER/REPO

What it means

The `repo` string must be either "OWNER/REPO" (2 slash-separated parts) or "HOST/OWNER/REPO" (3 parts) so it can target gh CLI --repo lookups. Any other slash count (0, 1, 4+) makes the value unresolvable and triggers this error, including the original repo string in quotes.

Source

Thrown at cmd/bd/gate.go:886

	var repoValue interface{}
	if err := json.Unmarshal(repoRaw, &repoValue); err != nil {
		return "", fmt.Errorf("metadata.repo: %w", err)
	}
	if repoValue == nil {
		return "", fmt.Errorf("metadata.repo must not be null")
	}
	repo, ok := repoValue.(string)
	if !ok {
		return "", fmt.Errorf("metadata.repo must be a string, got %T", repoValue)
	}
	if repo == "" {
		return "", nil
	}

	parts := strings.Split(repo, "/")
	if len(parts) != 2 && len(parts) != 3 {
		return "", fmt.Errorf("repo %q must use OWNER/REPO or HOST/OWNER/REPO", repo)
	}
	for _, part := range parts {
		if part == "" {
			return "", fmt.Errorf("repo %q contains an empty path component", repo)
		}
		for _, char := range part {
			if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') ||
				(char >= '0' && char <= '9') || char == '-' || char == '_' || char == '.' {
				continue
			}
			return "", fmt.Errorf("repo %q contains invalid character %q", repo, char)
		}
	}

	return repo, nil
}

// isGitHubGateType returns true for gate types whose condition is checked

View on GitHub (pinned to 71377f2769)

Solutions

  1. Change the value to "owner/repo", e.g. "gastownhall/beads".
  2. For a self-hosted GH instance use "host/owner/repo", e.g. "github.example.com/acme/api".
  3. Strip URL schemes/host paths: convert "https://github.com/owner/repo" to "owner/repo" (or "github.com/owner/repo" for the 3-part form).
  4. Re-run the gate check to confirm the repo resolves.

Example fix

// before
{"repo": "https://github.com/gastownhall/beads"}
// after
{"repo": "gastownhall/beads"}
Defensive patterns

Strategy: validation

Validate before calling

func validRepoShape(repo string) bool {
    parts := strings.Split(repo, "/")
    return len(parts) == 2 || len(parts) == 3
}
// call before storing metadata: if !validRepoShape(repo) { ... }

Type guard

func isOwnerRepoOrHostOwnerRepo(s string) bool {
    n := len(strings.Split(s, "/"))
    return n == 2 || n == 3
}

Prevention

When it happens

Trigger: metadata.repo set to values like "myrepo", "owner" (no slash), or "https://github.com/owner/repo" (contains 3+ slashes after splitting on "/") while running gate checks that resolve the GitHub repo.

Common situations: Users pasting a full GitHub URL instead of the owner/repo path; typing just a repo name assuming a default owner; including a protocol or trailing slash in the value.

Related errors


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