gastownhall/beads · error · storage.ErrPrefixMismatch
%w: issue ID %s does not match configured prefix %s
Error message
%w: issue ID %s does not match configured prefix %s
What it means
ValidateIssueIDPrefix enforces that an explicitly supplied issue ID starts with the configured prefix (e.g. "bd-") for the repository, wrapping storage.ErrPrefixMismatch. This prevents cross-repo ID confusion: beads repos are expected to own a distinct prefix so IDs from different databases never collide. The error lists the offending ID and the configured prefix.
Source
Thrown at internal/storage/issueops/create.go:580
}
return nil
}
// ValidateIssueIDPrefix validates that the issue ID matches the configured prefix
// or any of the allowed_prefixes.
func ValidateIssueIDPrefix(id, prefix, allowedPrefixes string) error {
if strings.HasPrefix(id, prefix+"-") {
return nil
}
if allowedPrefixes != "" {
for _, allowed := range strings.Split(allowedPrefixes, ",") {
allowed = strings.TrimSpace(allowed)
if allowed != "" && strings.HasPrefix(id, allowed+"-") {
return nil
}
}
}
return fmt.Errorf("%w: issue ID %s does not match configured prefix %s", storage.ErrPrefixMismatch, id, prefix)
}
// ParseHierarchicalID checks if an ID is hierarchical (e.g., "bd-abc.1")
// and returns the parent ID and child number.
func ParseHierarchicalID(id string) (parentID string, childNum int, ok bool) {
lastDot := strings.LastIndex(id, ".")
if lastDot == -1 {
return "", 0, false
}
parentID = id[:lastDot]
var num int
if _, err := fmt.Sscanf(id[lastDot+1:], "%d", &num); err != nil {
return "", 0, false
}
return parentID, num, true
}
// AllWisps returns true if every issue in the slice should be routed to theView on GitHub (pinned to 71377f2769)
Solutions
- Remap the issue ID to use the current repo's prefix (e.g. "bd-<hash>") before creating it.
- Update the configured allowed prefixes (.beads/config or equivalent) to include the prefix of the ID you are inserting.
- Let beads assign the ID (omit the explicit ID) instead of supplying a foreign-prefixed one.
- If you intentionally need a foreign ID, use the documented force/override option if available; otherwise keep the data in its own prefixed repo.
Example fix
// before issue.ID = "gt-abc123" // repo prefix is "bd" err := issueops.PreparePublicCreateRequest(...) // ErrPrefixMismatch // after issue.ID = "bd-abc123" // matches configured prefix, or leave ID empty to auto-assign err := issueops.PreparePublicCreateRequest(...)
Defensive patterns
Strategy: validation
Validate before calling
prefix := cfg.IssuePrefix // e.g. "bd"
if issue.ID != "" && !strings.HasPrefix(issue.ID, prefix+"-") {
issue.ID = prefix + "-" + strings.TrimPrefix(issue.ID, prefix+"-")
} Type guard
func hasValidPrefix(id, prefix string) bool {
return id == "" || strings.HasPrefix(id, strings.TrimSpace(prefix)+"-")
} Try / catch
if err := createIssue(issue); err != nil {
if errors.Is(err, storage.ErrPrefixMismatch) {
issue.ID = remapPrefix(issue.ID, cfg.IssuePrefix)
return createIssue(issue)
}
return err
} Prevention
- Never hardcode issue IDs; omit the ID and let beads assign one.
- Check the repo's configured prefix before importing external JSONL.
- Remap prefixes automatically in import tooling.
- Document the repo prefix for everyone writing scripts against it.
When it happens
Trigger: Creating an issue with an explicit ID whose prefix is not in the allowed-prefix configuration (e.g. inserting an issue with ID "gt-abc" into a repo configured with prefix "bd"), via assignCreateIssueIDInTx or PreparePublicCreateRequest with a caller-supplied ID.
Common situations: Importing JSONL from a different beads repo without remapping prefixes; hardcoding IDs with the wrong prefix in scripts; renaming a repo's prefix but reusing old IDs; cross-replica sync tooling that copies IDs verbatim between differently-prefixed repos.
Related errors
- no store is open for this workspace
- not found
- db: ChildCounterSQLRepository.NextChildID: parentID must not
- db: DependencySQLRepository.Insert: dep must not be nil
- db: DependencySQLRepository.Insert: IssueID must not be empt
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/16c2a573ca8e3692.
Report an issue: GitHub.