bytebase/bytebase · error
failed to commit empty UI Plan draft backfill batch
Error message
failed to commit empty UI Plan draft backfill batch
What it means
This error wraps a database transaction Commit failure that occurs when migrate3_21_1Batch finds zero eligible UI Plan draft candidates in the current batch and commits the (empty) transaction, releasing the plan row locks acquired earlier. The migration itself is fine; the wrapped cause is the underlying Postgres error from COMMIT. It is only thrown when the advisory-locked rows turned out to be already handled or filtered out by the re-check query.
Source
Thrown at backend/migrator/migration_3_21_1.go:206
key := candidate.projectID + "/" + strconv.FormatInt(candidate.planID, 10)
if err := store.AcquireAdvisoryXactLockWithStringKey(
ctx,
tx,
store.AdvisoryLockKeyPlanIssueRollout,
key,
); err != nil {
return errors.Wrapf(err, "failed to lock Plan %s", key)
}
planIDs = append(planIDs, candidate.planID)
}
eligible, err := findMigration3_21_1Candidates(ctx, tx, migrationTime, projectID, planIDs, nil, nil, 0, true)
if err != nil {
return err
}
if len(eligible) == 0 {
if err := tx.Commit(); err != nil {
return errors.Wrap(err, "failed to commit empty UI Plan draft backfill batch")
}
return nil
}
var lockedProjectID string
if err := tx.QueryRowContext(ctx, `
SELECT resource_id
FROM project
WHERE resource_id = $1
FOR UPDATE`, projectID).Scan(&lockedProjectID); err != nil {
return errors.Wrapf(err, "failed to lock project %s", projectID)
}
var issueID int64
if err := tx.QueryRowContext(ctx, `
SELECT GREATEST(COALESCE(MAX(id), 0), 100)
FROM issue
WHERE project = $1`, projectID).Scan(&issueID); err != nil {View on GitHub (pinned to 1870550677)
Solutions
- Check the wrapped cause (err.Cause() / logs) for the actual Postgres COMMIT error and fix it (network, timeout, connection pool settings).
- Re-run the migration: the batch transaction rolled back atomically, so it is safe to retry the 3.21.1 migration.
- Ensure only one Bytebase instance runs migrations at once; the advisory locks only serialize plan-level, not instance-level, work (see withMigrationGuard).
- Verify metadata DB health (pg_stat_activity for blocking sessions, statement_timeout) before retrying.
Example fix
// before: batch commit fails silently amid connection churn
if err := tx.Commit(); err != nil {
return errors.Wrap(err, "failed to commit empty UI Plan draft backfill batch")
}
// after: fail fast on a cancelled/deadline-exceeded context before committing
if err := ctx.Err(); err != nil {
return errors.Wrap(err, "migration context cancelled before commit")
}
if err := tx.Commit(); err != nil {
return errors.Wrap(err, "failed to commit empty UI Plan draft backfill batch")
} Defensive patterns
Strategy: retry
Validate before calling
// before upgrading: ensure only one instance migrates and the DB is reachable
if err := db.PingContext(ctx); err != nil { return err }
// SELECT pg_try_advisory_lock(...) to check no other migrator is active Try / catch
err := runMigration(ctx)
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
log.Printf("commit failed: %s (code %s), safe to retry", pgErr.Message, pgErr.Code)
return runMigration(ctx) // batch tx rolled back; retry is safe
}
return err Prevention
- Run schema migrations from a single instance only
- Check DB connectivity and statement_timeout before starting upgrades
- Retry failed migrations — batch transactions are atomic
- Monitor pg_stat_activity for blocking sessions during upgrades
When it happens
Trigger: Calling migrate3_21_1Batch with candidate rows whose per-plan advisory locks were acquired, but findMigration3_21_1Candidates returns zero eligible rows (e.g. another worker already inserted the draft issue between the initial listing and this batch), and then database.Tx.Commit fails due to connection drop, serialization/conflict, statement timeout, or the server shutting down mid-migration.
Common situations: Running the 3.21.1 upgrade against a production Postgres that drops connections or hits a lock conflict with a concurrently running Bytebase instance; terminating the migration midway (context cancellation); network partition between the migrator and the metadata database during a large upgrade.
Related errors
- failed to commit UI Plan draft backfill batch
- failed to commit migration guard transaction
- failed to commit UI Plan high-water capture
- failed to begin UI Plan draft backfill batch
- failed to lock project %s
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/87092216ea33a5ae.
Report an issue: GitHub.