gastownhall/beads · error

failed to begin regular tx: %w

Error message

failed to begin regular tx: %w

What it means

After reading the active branch, runDoltTransaction begins the regular SQL transaction with conn.BeginTx(ctx, nil). This error wraps a failure to start that transaction on the pinned connection — the session died between the branch read and BEGIN, the context was canceled, or the server rejected the transaction start (e.g. server shutting down, lock-table unavailable).

Source

Thrown at internal/storage/dolt/transaction.go:196

			doltMetrics.poolWaitCount.Add(ctx, statsAfter.WaitCount-statsBefore.WaitCount)
			waitMs := float64(statsAfter.WaitDuration-statsBefore.WaitDuration) / float64(time.Millisecond)
			doltMetrics.poolWaitMs.Record(ctx, waitMs)
		}
	}

	if err != nil {
		return fmt.Errorf("failed to acquire connection: %w", err)
	}
	defer conn.Close()

	var currentBranch string
	if err := conn.QueryRowContext(ctx, "SELECT active_branch()").Scan(&currentBranch); err != nil {
		return fmt.Errorf("failed to read active branch: %w", err)
	}

	regularTx, err := conn.BeginTx(ctx, nil)
	if err != nil {
		return fmt.Errorf("failed to begin regular tx: %w", err)
	}

	// The journal counter and rows must commit in the SAME SQL transaction as
	// every mutation they describe. bd_events_journal and bd_events_seq are
	// dolt_ignored, so on the default split-transaction shape they would land in
	// the ignored transaction while the mutation lands in the regular one: a
	// mixed durable+wisp callback would then make the two transactions contend
	// with each other on the single bd_events_seq row, and the ignored commit
	// can fail AFTER the regular side has already committed — a mutation with no
	// journal record, which is exactly the state the same-transaction guarantee
	// exists to make impossible. In journal mode both planes therefore share the
	// pinned regular transaction. The default journal-off path keeps the
	// established split transactions untouched.
	journalEnabled := s.eventsJournalEnabled.Load()
	ignoredTx := regularTx
	if !journalEnabled {
		// NOTE (GH#3140 metrics skew): the pool-wait bracket above measures only
		// the FIRST acquisition (the regular conn). A borrow inside

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the operation — this is a pre-callback setup failure and withTransactionSetupRetry will retry it
  2. Check Dolt server logs for shutdown/storage errors at the failure time
  3. Widen the context deadline if it expired during BeginTx
  4. Ensure only one process has the embedded Dolt database open if running in embedded mode
Defensive patterns

Strategy: retry

Try / catch

// runInTransaction already retries pre-callback failures via withTransactionSetupRetry;
// if you handle it manually:
if err != nil && callbackNotStarted(err) {
    return withTransactionSetupRetry(ctx, attempt)
}

Prevention

When it happens

Trigger: ctx canceled/deadline exceeded exactly during BeginTx; connection dropped after `SELECT active_branch()` succeeded; Dolt server refusing new transactions (shutdown, storage error); server-side session killed.

Common situations: Flaky network to a remote Dolt server; graceful-shutdown windows where the server stops accepting transactions; embedded Dolt process exiting under memory pressure; very tight per-operation timeouts.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/73ae7bf1b5d86b86. Report an issue: GitHub.