apache/answer · error

%s activity not exist

Error message

%s activity not exist

What it means

Returned by cancelActivities in the answer activity repo when an expected activity record is not found in the database before cancellation. When cancelling answer-related activities, each activity must exist; if the ID lookup finds no row, this domain error aborts the cancellation. Unlike the migration errors it is a business-logic existence check, not a driver failure.

Source

Thrown at internal/repo/activity/answer_repo.go:224

		}
	}
	return nil
}

// cancelActivities cancel activities
// If this activity is already cancelled, set activity rank to 0
// So after this function, the activity rank will be correct for update user rank
func (ar *AnswerActivityRepo) cancelActivities(session *xorm.Session, activities []*entity.Activity) (err error) {
	for _, act := range activities {
		t := &entity.Activity{}
		exist, err := session.ID(act.ID).Get(t)
		if err != nil {
			log.Error(err)
			return err
		}
		if !exist {
			log.Error(fmt.Errorf("%s activity not exist", act.ID))
			return fmt.Errorf("%s activity not exist", act.ID)
		}
		//  If this activity is already cancelled, set activity rank to 0
		if t.Cancelled == entity.ActivityCancelled {
			act.Rank = 0
		}
		if _, err = session.ID(act.ID).Cols("cancelled", "cancelled_at").
			Update(&entity.Activity{
				Cancelled:   entity.ActivityCancelled,
				CancelledAt: time.Now(),
			}); err != nil {
			log.Error(err)
			return err
		}
	}
	return nil
}

func (ar *AnswerActivityRepo) changeUserRank(ctx context.Context, session *xorm.Session,

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Verify the activity row with the logged act.ID exists in the activity table
  2. Check for cleanup/purge jobs that delete activities referenced by answers
  3. Make cancellation tolerant: skip missing activities instead of failing the whole operation if partial cancellation is acceptable
  4. Re-run in a transaction so activity and answer changes stay consistent

Example fix

// before
if !exist {
    log.Error(fmt.Errorf("%s activity not exist", act.ID))
    return fmt.Errorf("%s activity not exist", act.ID)
}
// after
if !exist {
    log.Warnf("activity %s not exist, skipping", act.ID)
    continue
}
Defensive patterns

Strategy: validation

Validate before calling

// before cancelling, confirm the activity exists
var count int64
session.Where("id = ?", act.ID).Count(&entity.Activity{}, &count)
if count == 0 {
    log.Warnf("activity %s missing; skip cancel", act.ID)
    continue
}

Try / catch

if err := repo.CancelAnswerActivities(ctx, answerID); err != nil {
    if strings.HasSuffix(err.Error(), "activity not exist") {
        // tolerate missing activity: log and continue
        log.Warnf("skip cancel: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Cancelling answer activities where the activity referenced by act.ID was deleted, never created, or belongs to another data set — the session/transaction Find reports exist=false for the activity ID.

Common situations: Data drift between the activity table and answer data (activities purged by cleanup jobs while answers remain); cancelling an answer twice after a partial rollback; environments where activity seeding was skipped.

Related errors


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