apache/answer · error
badge not exist
Error message
badge not exist
What it means
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.
Source
Thrown at internal/repo/badge_award/badge_award_repo.go:64
}
// AwardBadgeForUser award badge for user
func (r *badgeAwardRepo) AwardBadgeForUser(ctx context.Context, badgeAward *entity.BadgeAward) (err error) {
badgeAward.ID, err = r.uniqueIDRepo.GenUniqueIDStr(ctx, entity.BadgeAward{}.TableName())
if err != nil {
return err
}
_, err = r.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
session = session.Context(ctx)
badgeInfo := &entity.Badge{}
exist, err := session.ID(badgeAward.BadgeID).ForUpdate().Get(badgeInfo)
if err != nil {
return nil, err
}
if !exist {
return nil, fmt.Errorf("badge not exist")
}
old := &entity.BadgeAward{
UserID: badgeAward.UserID,
BadgeID: badgeAward.BadgeID,
IsBadgeDeleted: entity.IsBadgeNotDeleted,
}
if badgeInfo.Single != entity.BadgeSingleAward {
old.AwardKey = badgeAward.AwardKey
}
exist, err = session.Get(old)
if err != nil {
return nil, err
}
if exist {
return nil, fmt.Errorf("badge already awarded")
}
View on GitHub (pinned to 3b9f137061)
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.
Example fix
// before
if !exist {
return nil, fmt.Errorf("badge not exist")
}
// after
if !exist {
return nil, fmt.Errorf("badge not exist: id=%d", badgeAward.BadgeID)
} Defensive patterns
Strategy: validation
Validate before calling
var badge entity.Badge
exist, err := db.ID(badgeID).Get(&badge)
if err == nil && !exist {
return fmt.Errorf("badge %d does not exist, cannot award", badgeID)
} Type guard
func badgeExists(badges []entity.Badge, id int64) bool {
for _, b := range badges {
if b.ID == id {
return true
}
}
return false
} Try / catch
award, err := badgeAwardRepo.Award(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "badge not exist") {
return http.StatusNotFound, "badge does not exist"
}
return http.StatusInternalServerError, err.Error()
} Prevention
- 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.
When it happens
Trigger: Awarding a badge with a BadgeID that has no matching badges row — deleted badge, wrong ID, or unseeded badge data.
Common situations: 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.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- %s activity not exist
- badge already awarded
- config not found by id: %d
- config not found by key: %s
- get config failed: %w
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/1352972555bd440c.
Report an issue: GitHub.