bytebase/bytebase · error
failed to refresh active stale plan check run for approval i
Error message
failed to refresh active stale plan check run for approval input version
What it means
Error refreshing a plan check run whose status is still Available/Running but whose stored approval input version no longer matches the plan's current one (the plan changed mid-flight). The evaluator creates a fresh check run so the scheduler re-checks against the new inputs; failure is logged with structured fields and wrapped.
Source
Thrown at backend/component/review/evaluator.go:669
if planCheckRun.Status == store.PlanCheckRunStatusAvailable || planCheckRun.Status == store.PlanCheckRunStatusRunning {
if planCheckRun.Result.GetApprovalInputVersion() == approvalInputVersion {
return nil, approvalInputVersion, false, nil
}
refreshed, err := stores.CreatePlanCheckRun(ctx, &store.PlanCheckRunMessage{
ProjectID: issue.ProjectID,
PlanUID: plan.UID,
Result: &storepb.PlanCheckRunResult{
ApprovalInputVersion: approvalInputVersion,
},
})
if err != nil {
slog.Error("failed to refresh active stale plan check run for approval input version",
slog.String("project", issue.ProjectID),
slog.Int64("issue_uid", issue.UID),
slog.Int64("plan_uid", plan.UID),
slog.Int64("approval_input_version", approvalInputVersion),
log.BBError(err))
return nil, approvalInputVersion, false, errors.Wrap(err, "failed to refresh active stale plan check run for approval input version")
}
_ = refreshed
return nil, approvalInputVersion, false, nil
}
current, pending := isPlanCheckRunCurrentForApprovalInputVersion(planCheckRun, approvalInputVersion)
if pending {
return nil, approvalInputVersion, false, nil
}
if !current {
refreshed, err := stores.RefreshPlanCheckRunIfStaleApprovalInputVersion(ctx, issue.ProjectID, plan.UID, approvalInputVersion)
if err != nil {
slog.Error("failed to refresh stale plan check run for approval input version",
slog.String("project", issue.ProjectID),
slog.Int64("issue_uid", issue.UID),
slog.Int64("plan_uid", plan.UID),
slog.Int64("approval_input_version", approvalInputVersion),
log.BBError(err))
return nil, approvalInputVersion, false, errors.Wrap(err, "failed to refresh stale plan check run for approval input version")View on GitHub (pinned to 1870550677)
Solutions
- If the wrapped cause is a duplicate-key error, re-read the plan check run — the concurrent refresher likely succeeded.
- Verify metadata Postgres accepts writes (read-only mode, disk space).
- Retry the evaluation after transient failures.
- Serialize refreshes per-plan (advisory lock or single-writer scheduler) to avoid races.
Example fix
// before
_, err := stores.CreatePlanCheckRun(ctx, msg)
if err != nil { return errors.Wrap(err, "failed to refresh active stale plan check run...") }
// after: upsert instead of insert
_, err := stores.UpsertPlanCheckRun(ctx, msg) // ON CONFLICT (project, plan_uid) DO UPDATE
if err != nil { return errors.Wrap(err, "...") } Defensive patterns
Strategy: retry
Validate before calling
// detect stale version before refreshing
current, pending := isPlanCheckRunCurrentForApprovalInputVersion(planCheckRun, approvalInputVersion)
if pending || current { return nil } // no refresh needed Try / catch
if _, err := stores.CreatePlanCheckRun(ctx, msg); err != nil {
if isUniqueViolation(err) { return nil } // another refresher won
slog.Error("failed to refresh active stale plan check run", log.BBError(err))
return errors.Wrap(err, "failed to refresh active stale plan check run for approval input version")
} Prevention
- Avoid editing plans while checks are running; bump approval input version deliberately.
- Use upsert semantics for refresh rows.
- Serialize refreshes per plan with an advisory lock.
- Verify DB writability (disk space, read-only mode) before bulk refreshes.
When it happens
Trigger: planCheckRun is Available/Running with a stale ApprovalInputVersion, and CreatePlanCheckRun fails while writing the replacement: unique-constraint race, metadata write failure, or connection loss.
Common situations: Plan edited while its check was running; two evaluators racing to refresh the same stale row; metadata DB read-only/full disk; deadlock with the check scheduler updating the same row.
Related errors
- failed to create missing plan check run for approval input v
- no update field specified
- iam policy etag mismatch
- no update field provided
- no fields to update
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/dc47b42ef5ab45f4.
Report an issue: GitHub.