{"record":{"id":"4c1a46327c14db2c","repo":"gastownhall/beads","slug":"invalid-id-format-s-expected-format-prefix-ha","errorCode":null,"errorMessage":"invalid ID format '%s' (expected format: prefix-hash or prefix-hash.number, e.g., 'bd-a3f8e9' or 'bd-a3f8e9.1')","messagePattern":"invalid ID format '(.+?)' \\(expected format: prefix-hash or prefix-hash\\.number, e\\.g\\., 'bd-a3f8e9' or 'bd-a3f8e9\\.1'\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validation/bead.go","lineNumber":66,"sourceCode":"\tpriority := ParsePriority(priorityStr)\n\tif priority == -1 {\n\t\treturn -1, fmt.Errorf(\"invalid priority %q (expected 0-4 or P0-P4, not words like high/medium/low)\", priorityStr)\n\t}\n\treturn priority, nil\n}\n\n// ValidateIDFormat validates that an ID has the correct format.\n// Supports: prefix-number (bd-42), prefix-hash (bd-a3f8e9), or hierarchical (bd-a3f8e9.1)\n// Also supports hyphenated prefixes like \"bead-me-up-3e9\" or \"web-app-abc123\".\n// Returns the prefix part or an error if invalid.\nfunc ValidateIDFormat(id string) (string, error) {\n\tif id == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\t// Must contain hyphen\n\tif !strings.Contains(id, \"-\") {\n\t\treturn \"\", fmt.Errorf(\"invalid ID format '%s' (expected format: prefix-hash or prefix-hash.number, e.g., 'bd-a3f8e9' or 'bd-a3f8e9.1')\", id)\n\t}\n\n\t// Use ExtractIssuePrefix which correctly handles hyphenated prefixes\n\t// by looking at the last hyphen and checking if suffix is hash-like.\n\t// This fixes the bug where \"bead-me-up-3e9\" was parsed as prefix \"bead\"\n\t// instead of \"bead-me-up\".\n\tprefix := utils.ExtractIssuePrefix(id)\n\n\treturn prefix, nil\n}\n\n// validatePrefix checks that the requested prefix matches the database prefix.\n// Returns an error if they don't match (unless force is true).\nfunc validatePrefix(requestedPrefix, dbPrefix string, force bool) error {\n\treturn validatePrefixWithAllowed(requestedPrefix, dbPrefix, \"\", force)\n}\n\n// validatePrefixWithAllowed checks that the requested prefix is allowed.","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/validation/bead.go#L48-L84","documentation":"ValidateIDFormat checks that an issue ID contains a hyphen so a prefix/hash can be split (it supports hyphenated prefixes like \"bead-me-up-3e9\" via ExtractIssuePrefix). It returns this error for any non-empty ID with no hyphen at all. Empty strings are allowed and return (\"\", nil).","triggerScenarios":"Calling validation.ValidateIDFormat with a bare hash (\"a3f8e9\"), a bare number (\"42\"), a URL, or any string lacking '-'. The error text is the format guidance shown back to the user.","commonSituations":"Users typing only the short hash they saw in a listing; scripts stripping the prefix; passing a GitHub issue number like \"42\"; copy/paste that dropped the \"bd-\" prefix; accidentally passing a title instead of an ID.","solutions":["Include the prefix: use \"bd-a3f8e9\" instead of \"a3f8e9\"","For hierarchical IDs use the dotted form \"bd-a3f8e9.1\"","If you only have a bare hash, prepend your configured prefix (e.g. \"bd-\" + hash) or resolve it via the partial-ID path which handles normalization","Handle empty input separately — it is valid and returns (\"\", nil)"],"exampleFix":"// before\nprefix, err := validation.ValidateIDFormat(\"a3f8e9\") // no hyphen\n// after\nprefix, err := validation.ValidateIDFormat(\"bd-a3f8e9\") // prefix-hash form","handlingStrategy":"validation","validationCode":"func hasIDShape(s string) bool {\n    s = strings.TrimSpace(s)\n    return s == \"\" || strings.Contains(s, \"-\")\n}\nif !hasIDShape(id) { return fmt.Errorf(\"%q needs a prefix, e.g. bd-%s\", id, id) }","typeGuard":"func isBareHash(s string) bool {\n    return s != \"\" && !strings.Contains(s, \"-\")\n}","tryCatchPattern":"prefix, err := validation.ValidateIDFormat(id)\nif err != nil {\n    // auto-heal: prepend the configured prefix and retry once\n    id = cfg.Prefix + \"-\" + id\n    prefix, err = validation.ValidateIDFormat(id)\n}","preventionTips":["Never pass bare hashes; always carry the \"<prefix>-\" into ID fields","Sanitize inputs that may be titles or numbers instead of IDs","Handle empty string as a valid no-op case before validation","When accepting user input, offer partial-ID resolution instead of requiring exact format"],"tags":["validation","id-format","input","go"],"backgroundTag":"invalid-id-format","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}