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

  1. Check the wrapped cause (err.Cause() / logs) for the actual Postgres COMMIT error and fix it (network, timeout, connection pool settings).
  2. Re-run the migration: the batch transaction rolled back atomically, so it is safe to retry the 3.21.1 migration.
  3. Ensure only one Bytebase instance runs migrations at once; the advisory locks only serialize plan-level, not instance-level, work (see withMigrationGuard).
  4. 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

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


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/87092216ea33a5ae. Report an issue: GitHub.