{"record":{"id":"a0d178c00c5dac3f","repo":"gastownhall/beads","slug":"prefix-mismatch-database-uses-s-allowed-s","errorCode":null,"errorMessage":"prefix mismatch: database uses '%s' (allowed: %s) but you specified '%s' (use --force to override)","messagePattern":"prefix mismatch: database uses '(.+?)' \\(allowed: (.+?)\\) but you specified '(.+?)' \\(use --force to override\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validation/bead.go","lineNumber":120,"sourceCode":"\t// Check if requestedPrefix is in the allowed list or is a prefix of an allowed entry\n\tif allowedPrefixes != \"\" {\n\t\tfor _, allowed := range strings.Split(allowedPrefixes, \",\") {\n\t\t\tallowed = strings.TrimSpace(allowed)\n\t\t\tif allowed == requestedPrefix {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\t// GH#1135: Also accept if requestedPrefix is a prefix of an allowed entry.\n\t\t\t// This handles IDs like \"hq-cv-test\" where extraction yields \"hq\" but\n\t\t\t// the user configured \"hq-cv\" in allowed_prefixes.\n\t\t\tif strings.HasPrefix(allowed, requestedPrefix+\"-\") {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build helpful error message\n\tif allowedPrefixes != \"\" {\n\t\treturn fmt.Errorf(\"prefix mismatch: database uses '%s' (allowed: %s) but you specified '%s' (use --force to override)\",\n\t\t\tdbPrefix, allowedPrefixes, requestedPrefix)\n\t}\n\treturn fmt.Errorf(\"prefix mismatch: database uses '%s' but you specified '%s' (use --force to override)\", dbPrefix, requestedPrefix)\n}\n\n// ValidateIDPrefixAllowed checks that an issue ID's prefix is allowed.\n// Unlike validatePrefixWithAllowed which takes an extracted prefix, this function\n// takes the full ID and checks if it starts with any allowed prefix.\n// This correctly handles multi-hyphen prefixes like \"hq-cv-\" where the suffix\n// might look like an English word (e.g., \"hq-cv-test\").\n// (GH#1135)\n//\n// It matches if:\n// - force is true\n// - dbPrefix is empty\n// - id starts with dbPrefix + \"-\"\n// - id starts with any prefix in allowedPrefixes + \"-\"\n// Returns an error if none of these conditions are met.","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/validation/bead.go#L102-L138","documentation":"validatePrefixWithAllowed enforces that the prefix you are creating issues with matches the database's configured prefix (or an entry in the comma-separated allowed_prefixes list, or a prefix of one). When allowedPrefixes is configured and the requested prefix matches none of them, it returns this message telling you the DB prefix, the allowed set, what you specified, and that --force overrides.","triggerScenarios":"Creating/validating issues where the requested prefix differs from dbPrefix and is neither equal to any allowed_prefixes entry nor a \"<requested>-\" prefix of one, with force=false. E.g. DB uses \"bd\", allowed \"hq-cv\", user requests \"web\".","commonSituations":"Cloning a repo whose .beads config uses a different prefix; renaming a project and forgetting to update the prefix config; multi-team setups where each team's prefix must be added to allowed_prefixes; typos in the allowed_prefixes CSV.","solutions":["Use the database's prefix (shown in the error) for new issues","Add your prefix to allowed_prefixes in config if multiple prefixes are legitimate","Re-run with --force if you truly intend a divergent prefix (e.g. migration)","Check for typos and trailing hyphens in the requested prefix vs the allowed list"],"exampleFix":"// before\nerr := validation.ValidateIDPrefixAllowed(\"web-abc123\", \"bd\", \"hq-cv\", false) // mismatch\n// after\n// option 1: use the right prefix\nerr := validation.ValidateIDPrefixAllowed(\"hq-cv-abc123\", \"bd\", \"hq-cv\", false)\n// option 2: allow it\n// config: allowed_prefixes = \"hq-cv,web\" or pass force=true","handlingStrategy":"validation","validationCode":"requested := utils.ExtractIssuePrefix(id)\nallowed := strings.Split(cfg.AllowedPrefixes, \",\")\nok := requested == cfg.Prefix\nfor _, a := range allowed {\n    a = strings.TrimSpace(a)\n    if requested == a || strings.HasPrefix(a, requested+\"-\") { ok = true }\n}\nif !ok { return fmt.Errorf(\"prefix %q not allowed (db: %s, allowed: %s)\", requested, cfg.Prefix, cfg.AllowedPrefixes) }","typeGuard":null,"tryCatchPattern":"if err := validation.ValidateIDPrefixAllowed(id, cfg.Prefix, cfg.AllowedPrefixes, false); err != nil {\n    if !forceFlag { return err }\n    // proceed only with explicit user intent\n    _ = validation.ValidateIDPrefixAllowed(id, cfg.Prefix, cfg.AllowedPrefixes, true)\n}","preventionTips":["Check `bd config` / .beads settings for the prefix before creating IDs in a new checkout","Keep allowed_prefixes in sync across team members' clones","Never hard-code a prefix in scripts; read it from config","Avoid --force except for deliberate migrations"],"tags":["prefix","configuration","validation","go"],"backgroundTag":"prefix-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}