apache/answer · error
update question failed: %w
Error message
update question failed: %w
What it means
Wraps the xorm Update error when persisting a question's recomputed answer_count column during the v13 migration. The row-level UPDATE on the question table failed; the migration logs the offending item and aborts so the failure is visible.
Source
Thrown at internal/migrations/v13.go:165
_, ok := questionAnswerCount[answer.QuestionID]
if !ok {
questionAnswerCount[answer.QuestionID] = 1
} else {
questionAnswerCount[answer.QuestionID]++
}
}
questionList := make([]QuestionV13, 0)
err = x.Context(ctx).Find(&questionList, &QuestionV13{})
if err != nil {
return fmt.Errorf("get questions failed: %w", err)
}
for _, item := range questionList {
_, ok := questionAnswerCount[item.ID]
if ok {
item.AnswerCount = questionAnswerCount[item.ID]
if _, err = x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err != nil {
log.Errorf("update %+v config failed: %s", item, err)
return fmt.Errorf("update question failed: %w", err)
}
}
}
return nil
}
// updateTagCount update tag count
func updateTagCount(ctx context.Context, x *xorm.Engine) error {
tagRelList := make([]entity.TagRel, 0)
err := x.Context(ctx).Find(&tagRelList, &entity.TagRel{})
if err != nil {
return fmt.Errorf("get tag rel failed: %w", err)
}
questionIDs := make([]string, 0)
questionsAvailableMap := make(map[string]bool)
questionsHideMap := make(map[string]bool)
for _, item := range tagRelList {View on GitHub (pinned to 3b9f137061)
Solutions
- Check the wrapped driver error for lock timeout vs missing column
- Confirm answer_count column exists (run the v13 DDL first)
- Retry the migration after connection is restored; already-updated rows are safe to re-update
- Run migrations during a maintenance window to avoid concurrent write contention
Example fix
// before
if _, err = x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err != nil {
return fmt.Errorf("update question failed: %w", err)
}
// after
// ensure column exists before loop
if has, _ := x.Context(ctx).IsColumnExist("question", "answer_count"); !has {
return fmt.Errorf("column answer_count missing; run schema migration first")
} Defensive patterns
Strategy: retry
Validate before calling
if has, _ := x.Context(ctx).IsColumnExist("question", "answer_count"); !has {
return fmt.Errorf("answer_count column missing; apply schema change first")
} Try / catch
for attempt := 0; attempt < 3; attempt++ {
if _, err = x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}); err == nil {
break
}
time.Sleep(time.Duration(attempt+1) * time.Second)
} Prevention
- Run schema DDL before data backfill in the same migration
- Schedule migrations in maintenance windows to avoid lock contention
- Set reasonable innodb_lock_wait_timeout / statement timeouts
- Make update loops idempotent so retries are safe
When it happens
Trigger: x.Context(ctx).Cols("answer_count").Update(item, &QuestionV13{ID: item.ID}) failing because the connection dropped mid-loop, answer_count column does not exist (schema not yet migrated), a lock/timeout on the row, or context cancellation.
Common situations: Migrating a large question table over a flaky connection; running the code before the v13 schema change added answer_count; deadlocks with concurrent writers to the question table.
Related errors
- %s failed: %s
- sync version failed: %v
- get config failed: %w
- update config failed: %w
- add config failed: %w
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/051961b926222722.
Report an issue: GitHub.