gastownhall/beads · error

invalid GitHub issue number %q: %w

Error message

invalid GitHub issue number %q: %w

What it means

Tracker.FetchIssue expects a GitHub issue number as a plain numeric string ("123") and converts it with strconv.Atoi. When the identifier is not a valid integer, the Atoi error is wrapped with the original identifier so the caller can see what was rejected.

Source

Thrown at internal/github/tracker.go:121

		issues, err = t.client.FetchIssuesSince(ctx, state, *opts.Since)
	} else {
		issues, err = t.client.FetchIssues(ctx, state)
	}
	if err != nil {
		return nil, err
	}

	result := make([]tracker.TrackerIssue, 0, len(issues))
	for _, gh := range issues {
		result = append(result, githubToTrackerIssue(&gh))
	}
	return result, nil
}

func (t *Tracker) FetchIssue(ctx context.Context, identifier string) (*tracker.TrackerIssue, error) {
	number, err := strconv.Atoi(identifier)
	if err != nil {
		return nil, fmt.Errorf("invalid GitHub issue number %q: %w", identifier, err)
	}

	gh, err := t.client.FetchIssueByNumber(ctx, number)
	if err != nil {
		return nil, err
	}
	if gh == nil {
		return nil, nil
	}

	ti := githubToTrackerIssue(gh)
	return &ti, nil
}

func (t *Tracker) CreateIssue(ctx context.Context, issue *types.Issue) (*tracker.TrackerIssue, error) {
	fields := BeadsIssueToGitHubFields(issue, t.config)
	labels, _ := fields["labels"].([]string)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Strip non-numeric prefixes: pass "123" instead of "#123" or a URL.
  2. Extract the number from a URL if needed (everything after the last '/').
  3. Resolve the correct GitHub issue number first (e.g. via a search/list call) if you only have a title or slug.
  4. Validate the identifier with strconv.Atoi in your own code before calling FetchIssue for a friendlier error.

Example fix

// before
issue, err := t.FetchIssue(ctx, "#42")
// after
issue, err := t.FetchIssue(ctx, "42")
Defensive patterns

Strategy: validation

Validate before calling

func normalizeIssueNumber(id string) (int, error) {
    id = strings.TrimPrefix(strings.TrimSpace(id), "#")
    if u, err := url.Parse(id); err == nil && u.Path != "" { id = path.Base(u.Path) }
    return strconv.Atoi(id)
}

Try / catch

n, aerr := strconv.Atoi(identifier)
if aerr != nil { return fmt.Errorf("%q is not a GitHub issue number", identifier) } // pre-check before FetchIssue

Prevention

When it happens

Trigger: Calling FetchIssue with identifiers like "#123", "ISSUE-123", a URL, an empty string, or a slug — anything Atoi cannot parse as an integer.

Common situations: Passing a full GitHub issue URL or "#123" copied from the UI, passing a beads issue key instead of a GitHub number, or feeding output of another tool directly into FetchIssue.

Related errors


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