{"record":{"id":"16c2a573ca8e3692","repo":"gastownhall/beads","slug":"w-issue-id-s-does-not-match-configured-prefix-16c2a5","errorCode":null,"errorMessage":"%w: issue ID %s does not match configured prefix %s","messagePattern":"%w: issue ID (.+?) does not match configured prefix (.+?)","errorType":"validation","errorClass":"storage.ErrPrefixMismatch","httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/create.go","lineNumber":580,"sourceCode":"\t}\n\treturn nil\n}\n\n// ValidateIssueIDPrefix validates that the issue ID matches the configured prefix\n// or any of the allowed_prefixes.\nfunc ValidateIssueIDPrefix(id, prefix, allowedPrefixes string) error {\n\tif strings.HasPrefix(id, prefix+\"-\") {\n\t\treturn nil\n\t}\n\tif allowedPrefixes != \"\" {\n\t\tfor _, allowed := range strings.Split(allowedPrefixes, \",\") {\n\t\t\tallowed = strings.TrimSpace(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\treturn fmt.Errorf(\"%w: issue ID %s does not match configured prefix %s\", storage.ErrPrefixMismatch, id, prefix)\n}\n\n// ParseHierarchicalID checks if an ID is hierarchical (e.g., \"bd-abc.1\")\n// and returns the parent ID and child number.\nfunc ParseHierarchicalID(id string) (parentID string, childNum int, ok bool) {\n\tlastDot := strings.LastIndex(id, \".\")\n\tif lastDot == -1 {\n\t\treturn \"\", 0, false\n\t}\n\tparentID = id[:lastDot]\n\tvar num int\n\tif _, err := fmt.Sscanf(id[lastDot+1:], \"%d\", &num); err != nil {\n\t\treturn \"\", 0, false\n\t}\n\treturn parentID, num, true\n}\n\n// AllWisps returns true if every issue in the slice should be routed to the","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/create.go#L562-L598","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nissue.ID = \"gt-abc123\" // repo prefix is \"bd\"\nerr := issueops.PreparePublicCreateRequest(...) // ErrPrefixMismatch\n// after\nissue.ID = \"bd-abc123\" // matches configured prefix, or leave ID empty to auto-assign\nerr := issueops.PreparePublicCreateRequest(...)","handlingStrategy":"validation","validationCode":"prefix := cfg.IssuePrefix // e.g. \"bd\"\nif issue.ID != \"\" && !strings.HasPrefix(issue.ID, prefix+\"-\") {\n    issue.ID = prefix + \"-\" + strings.TrimPrefix(issue.ID, prefix+\"-\")\n}","typeGuard":"func hasValidPrefix(id, prefix string) bool {\n    return id == \"\" || strings.HasPrefix(id, strings.TrimSpace(prefix)+\"-\")\n}","tryCatchPattern":"if err := createIssue(issue); err != nil {\n    if errors.Is(err, storage.ErrPrefixMismatch) {\n        issue.ID = remapPrefix(issue.ID, cfg.IssuePrefix)\n        return createIssue(issue)\n    }\n    return err\n}","preventionTips":["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."],"tags":["validation","id-prefix","storage"],"backgroundTag":"issue-id-prefix-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}