{"record":{"id":"64fe8ea2164fee3a","repo":"gastownhall/beads","slug":"prefix-mismatch-database-uses-s-but-id-s-d","errorCode":null,"errorMessage":"prefix mismatch: database uses '%s-' but ID '%s' doesn't match (use --force to override)","messagePattern":"prefix mismatch: database uses '(.+?)-' but ID '(.+?)' doesn't match \\(use --force to override\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validation/bead.go","lineNumber":167,"sourceCode":"\n\t// Check if ID starts with any allowed prefix\n\tif allowedPrefixes != \"\" {\n\t\tfor _, allowed := range strings.Split(allowedPrefixes, \",\") {\n\t\t\tallowed = strings.TrimSpace(allowed)\n\t\t\t// Normalize: remove trailing - if present (we add it for matching)\n\t\t\tallowed = strings.TrimSuffix(allowed, \"-\")\n\t\t\tif allowed != \"\" && strings.HasPrefix(id, allowed+\"-\") {\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 ID '%s' doesn't match any allowed prefix (use --force to override)\",\n\t\t\tdbPrefix, allowedPrefixes, id)\n\t}\n\treturn fmt.Errorf(\"prefix mismatch: database uses '%s-' but ID '%s' doesn't match (use --force to override)\", dbPrefix, id)\n}\n","sourceCodeStart":149,"sourceCodeEnd":169,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/validation/bead.go#L149-L169","documentation":"The no-allowed-list variant of ValidateIDPrefixAllowed: when allowed_prefixes is empty and the ID does not start with \"<dbPrefix>-\", the function returns this message. Only force=true or an empty dbPrefix bypass it. It prevents mixing foreign-prefix issue IDs into a database with a single configured prefix.","triggerScenarios":"Calling ValidateIDPrefixAllowed with an ID like \"hq-cv-test\" in a database whose prefix is \"bd\" with no allowed list configured and force=false. Note the check is on the raw ID string, so even hyphenated prefixes not equal to dbPrefix are rejected here.","commonSituations":"Refs/issues imported from another beads repo; scripts hard-coding a prefix from a different project; users abbreviating or reformatting IDs (dropping/altering the prefix); config file with the wrong prefix for this checkout.","solutions":["Rewrite the ID with the database's prefix (shown in the message)","Fix your configured prefix if the DB prefix itself is wrong, then retry","Use --force / force=true only for intentional cross-prefix references (e.g. migration or federation)"],"exampleFix":"// before\nerr := validation.ValidateIDPrefixAllowed(\"hq-cv-test\", \"bd\", \"\", false) // mismatch\n// after\nerr := validation.ValidateIDPrefixAllowed(\"bd-test\", \"bd\", \"\", false)\n// or: validation.ValidateIDPrefixAllowed(\"hq-cv-test\", \"bd\", \"\", true) // override","handlingStrategy":"validation","validationCode":"if cfg.Prefix != \"\" && !strings.HasPrefix(id, strings.TrimSuffix(cfg.Prefix, \"-\")+\"-\") {\n    return fmt.Errorf(\"ID %q must start with %q-\", id, cfg.Prefix)\n}","typeGuard":null,"tryCatchPattern":"if err := validation.ValidateIDPrefixAllowed(id, dbPrefix, \"\", false); err != nil {\n    if !forceFlag { return err }\n    log.Printf(\"overriding prefix check for %q\", id)\n    _ = validation.ValidateIDPrefixAllowed(id, dbPrefix, \"\", true)\n}","preventionTips":["Learn the checkout's prefix (bd config) before generating IDs","Normalize imported IDs to the local prefix on ingest","Never strip or rewrite the prefix when copying IDs between tools","If you genuinely need multiple prefixes, configure allowed_prefixes rather than forcing"],"tags":["prefix","configuration","validation","id","go"],"backgroundTag":"prefix-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}