gastownhall/beads · error

prefix mismatch: database uses '%s-' (allowed: %s) but ID '%

Error message

prefix mismatch: database uses '%s-' (allowed: %s) but ID '%s' doesn't match any allowed prefix (use --force to override)

What it means

ValidateIDPrefixAllowed checks a full issue ID against the database prefix and an allowed_prefixes list (matching on prefix+'-' boundaries, which handles multi-hyphen prefixes like hq-cv). When an allowed list is configured and the ID starts with none of the allowed prefixes, it returns this message with the DB prefix, allowed list, offending ID, and the --force escape hatch.

Source

Thrown at internal/validation/bead.go:164

	if strings.HasPrefix(id, dbPrefix+"-") {
		return nil
	}

	// Check if ID starts with any allowed prefix
	if allowedPrefixes != "" {
		for _, allowed := range strings.Split(allowedPrefixes, ",") {
			allowed = strings.TrimSpace(allowed)
			// Normalize: remove trailing - if present (we add it for matching)
			allowed = strings.TrimSuffix(allowed, "-")
			if allowed != "" && strings.HasPrefix(id, allowed+"-") {
				return nil
			}
		}
	}

	// Build helpful error message
	if allowedPrefixes != "" {
		return fmt.Errorf("prefix mismatch: database uses '%s-' (allowed: %s) but ID '%s' doesn't match any allowed prefix (use --force to override)",
			dbPrefix, allowedPrefixes, id)
	}
	return fmt.Errorf("prefix mismatch: database uses '%s-' but ID '%s' doesn't match (use --force to override)", dbPrefix, id)
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use an ID whose prefix is in the allowed list (or the DB prefix)
  2. Add the ID's prefix to allowed_prefixes if it is legitimately part of this database
  3. Pass force=true / --force if the foreign-prefix ID is intentional (e.g. cross-references)
  4. Verify the ID is not a different tracker's identifier mistakenly supplied

Example fix

// before
err := validation.ValidateIDPrefixAllowed("gh-123", "bd", "hq-cv", false) // mismatch
// after
err := validation.ValidateIDPrefixAllowed("hq-cv-123", "bd", "hq-cv", false)
// or: validation.ValidateIDPrefixAllowed("gh-123", "bd", "hq-cv", true) // intentional override
Defensive patterns

Strategy: validation

Validate before calling

func idPrefixAllowed(id, dbPrefix, allowed string) bool {
    if strings.HasPrefix(id, strings.TrimSuffix(dbPrefix, "-")+"-") { return true }
    for _, a := range strings.Split(allowed, ",") {
        a = strings.TrimSuffix(strings.TrimSpace(a), "-")
        if a != "" && strings.HasPrefix(id, a+"-") { return true }
    }
    return false
}
if !idPrefixAllowed(id, cfg.Prefix, cfg.AllowedPrefixes) { return fmt.Errorf("prefix of %q not allowed", id) }

Try / catch

if err := validation.ValidateIDPrefixAllowed(id, dbPrefix, allowedPrefixes, false); err != nil {
    if !forceFlag { return err }
    _ = validation.ValidateIDPrefixAllowed(id, dbPrefix, allowedPrefixes, true)
}

Prevention

When it happens

Trigger: Calling ValidateIDPrefixAllowed with an ID like "web-abc123" where dbPrefix is "bd" and allowedPrefixes is e.g. "hq-cv,hn", and the ID starts with none of "bd-", "hq-cv-", "hn-", force=false.

Common situations: Cross-posting issues between repos with different prefixes; a typo in the ID; a team's prefix missing from allowed_prefixes after a re-org; external references (e.g. GH#123 style) passed where a beads ID is required.

Related errors


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