{"record":{"id":"1352972555bd440c","repo":"apache/answer","slug":"badge-not-exist","errorCode":null,"errorMessage":"badge not exist","messagePattern":"badge not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/repo/badge_award/badge_award_repo.go","lineNumber":64,"sourceCode":"}\n\n// AwardBadgeForUser award badge for user\nfunc (r *badgeAwardRepo) AwardBadgeForUser(ctx context.Context, badgeAward *entity.BadgeAward) (err error) {\n\tbadgeAward.ID, err = r.uniqueIDRepo.GenUniqueIDStr(ctx, entity.BadgeAward{}.TableName())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = r.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {\n\t\tsession = session.Context(ctx)\n\n\t\tbadgeInfo := &entity.Badge{}\n\t\texist, err := session.ID(badgeAward.BadgeID).ForUpdate().Get(badgeInfo)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !exist {\n\t\t\treturn nil, fmt.Errorf(\"badge not exist\")\n\t\t}\n\n\t\told := &entity.BadgeAward{\n\t\t\tUserID:         badgeAward.UserID,\n\t\t\tBadgeID:        badgeAward.BadgeID,\n\t\t\tIsBadgeDeleted: entity.IsBadgeNotDeleted,\n\t\t}\n\t\tif badgeInfo.Single != entity.BadgeSingleAward {\n\t\t\told.AwardKey = badgeAward.AwardKey\n\t\t}\n\t\texist, err = session.Get(old)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif exist {\n\t\t\treturn nil, fmt.Errorf(\"badge already awarded\")\n\t\t}\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/repo/badge_award/badge_award_repo.go#L46-L82","documentation":"Thrown in the badge-award repo when the badge referenced by badgeAward.BadgeID does not exist in the badges table. Like the user guard, it runs inside a ForUpdate() transaction so awarding is aborted before any insert when the badge row is missing.","triggerScenarios":"Awarding a badge with a BadgeID that has no matching badges row — deleted badge, wrong ID, or unseeded badge data.","commonSituations":"Badge definitions removed by an admin while old triggers/imports still reference them; fixtures missing badge seed rows; hardcoded badge IDs that changed between releases.","solutions":["Verify the badge ID exists: SELECT id FROM badges WHERE id = <id>;","Seed the badge definitions in the target environment before awarding.","Stop awarding deleted badges: filter out awards whose badge was deleted upstream.","Add an FK from badge_award.badge_id to badges.id for clearer failures."],"exampleFix":"// before\nif !exist {\n    return nil, fmt.Errorf(\"badge not exist\")\n}\n// after\nif !exist {\n    return nil, fmt.Errorf(\"badge not exist: id=%d\", badgeAward.BadgeID)\n}","handlingStrategy":"validation","validationCode":"var badge entity.Badge\nexist, err := db.ID(badgeID).Get(&badge)\nif err == nil && !exist {\n    return fmt.Errorf(\"badge %d does not exist, cannot award\", badgeID)\n}","typeGuard":"func badgeExists(badges []entity.Badge, id int64) bool {\n    for _, b := range badges {\n        if b.ID == id {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"award, err := badgeAwardRepo.Award(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"badge not exist\") {\n        return http.StatusNotFound, \"badge does not exist\"\n    }\n    return http.StatusInternalServerError, err.Error()\n}","preventionTips":["Keep badge seed migrations in sync across all environments.","Never hardcode badge IDs; resolve by stable badge key/name.","Skip awards whose badge has been deleted instead of passing the stale ID.","Add an FK from badge_award.badge_id to badges.id."],"tags":["database","badge","not-found"],"backgroundTag":"record-not-found","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}