gastownhall/beads · error
ambiguous: %q matches %d protos: %s Use the ID or a more s
Error message
ambiguous: %q matches %d protos: %s Use the ID or a more specific title
What it means
When resolveProtoIDOrTitle's title search matches multiple protos, it cannot choose for the user. It formats every match as 'ID: Title' and throws the 'ambiguous: ... matches %d protos' error, instructing the caller to use the exact ID or a more specific title. This is an intentional disambiguation guard, not a malfunction.
Source
Thrown at cmd/bd/template.go:309
if exactMatch != nil {
return exactMatch.ID, nil
}
if len(matches) == 0 {
return "", fmt.Errorf("no proto found matching %q (by ID or title)", input)
}
if len(matches) == 1 {
return matches[0].ID, nil
}
// Multiple matches - show them all for disambiguation
var matchNames []string
for _, m := range matches {
matchNames = append(matchNames, fmt.Sprintf("%s: %s", m.ID, m.Title))
}
return "", fmt.Errorf("ambiguous: %q matches %d protos:\n %s\nUse the ID or a more specific title", input, len(matches), strings.Join(matchNames, "\n "))
}
// extractVariables finds all {{variable}} patterns in text.
// Handlebars control keywords like "else", "this" are excluded.
func extractVariables(text string) []string {
matches := variablePattern.FindAllStringSubmatch(text, -1)
seen := make(map[string]bool)
var vars []string
for _, match := range matches {
if len(match) >= 2 && !seen[match[1]] {
name := match[1]
// Skip Handlebars control keywords
if isHandlebarsKeyword(name) {
continue
}
vars = append(vars, name)
seen[name] = true
}View on GitHub (pinned to 71377f2769)
Solutions
- Re-run the command with the proto's exact ID instead of its title.
- Use a longer, more specific title substring that matches only one proto.
- Rename duplicate protos to distinct titles to prevent future ambiguity.
- Delete or consolidate stale duplicate protos.
Example fix
// before bd mol pour deploy // ambiguous: matches 3 protos // after bd mol pour bd-abc123 // use the exact ID
Defensive patterns
Strategy: fallback
Validate before calling
// disambiguate up front:
matches := filterByName(protos, input)
if len(matches) > 1 { fmt.Println("use exact ID:"); for _, m := range matches { fmt.Println(m.ID, m.Title) } } Try / catch
pid, err := resolveProtoIDOrTitle(ctx, s, input)
if err != nil && strings.Contains(err.Error(), "ambiguous:") {
// parse listed matches from err and prompt user to choose an ID
return err
} Prevention
- Prefer exact IDs in scripts and CI.
- Rename protos so titles are unique.
- Avoid overly generic proto names.
When it happens
Trigger: Invoking a proto command with a title string that is a substring/prefix of, or otherwise matches, several template-labeled issues — e.g. two protos titled 'Deploy' and 'Deploy Service'.
Common situations: Generic proto names like 'test' or 'build' colliding across teams; duplicated protos created before a rename; case differences that the fuzzy matcher treats as matches.
Related errors
- no proto found matching %q (by ID or title)
- ErrAmbiguousID
- invalid format template: %w
- template execution error: %w
- template %s not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/63c8a63419e0f747.
Report an issue: GitHub.