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

  1. Verify the badge ID exists: SELECT id FROM badges WHERE id = <id>;
  2. Seed the badge definitions in the target environment before awarding.
  3. Stop awarding deleted badges: filter out awards whose badge was deleted upstream.
  4. 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

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


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/1352972555bd440c. Report an issue: GitHub.