gastownhall/beads · error

failed to set dolt_force_transaction_commit: %w

Error message

failed to set dolt_force_transaction_commit: %w

What it means

Thrown when the store fails to execute `SET @@dolt_force_transaction_commit = 1` on the pull transaction. Dolt refuses to commit a transaction that leaves commit conflicts; this session variable is set so the pull can land a merge with conflicts into the working set where bd can inspect and repair it. If the SET itself fails, the transaction is rolled back and the pull aborts with this wrapped cause.

Source

Thrown at internal/storage/dolt/store.go:4386

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

	// Allow commits with conflicts so we can inspect and resolve them.
	if _, err := tx.ExecContext(ctx, "SET @@dolt_allow_commit_conflicts = 1"); err != nil {
		_ = tx.Rollback()
		return pullReport{}, fmt.Errorf("failed to set dolt_allow_commit_conflicts: %w", err)
	}
	// bd-6dnrw.4: a merge that violates a foreign key (e.g. one clone deleted
	// an issue while another inserted a child row referencing it) rolls the
	// whole transaction back before it can be inspected. Let it land in the
	// working set instead so tryRepairFKCascadeViolations can apply the
	// cascade semantics; the violation check before tx.Commit() below refuses
	// to commit anything the repair did not fully clear.
	if _, err := tx.ExecContext(ctx, "SET @@dolt_force_transaction_commit = 1"); err != nil {
		_ = tx.Rollback()
		return pullReport{}, fmt.Errorf("failed to set dolt_force_transaction_commit: %w", err)
	}

	// DOLT_PULL's row is the engine's only in-band account of what the pull
	// did: `dolt pull` on the CLI exits 0 whether it merged or was already up
	// to date, and so does this CALL. Capturing it costs nothing — the drain
	// is identical — and it is the difference between a caller that knows
	// nothing arrived and one that only knows no error occurred (ga-bq9zd).
	pullRow, pullErr := schema.CallReturningRow(ctx, tx, query, args...)
	report := parseMergeReport(pullRow)

	// GH#3144: When DOLT_PULL fails because upstream branch tracking is not
	// configured in repo_state.json (common when remote was added via
	// bd dolt remote add rather than bd bootstrap/dolt clone), fall back to
	// DOLT_FETCH + DOLT_MERGE which does not require tracking config.
	if pullErr != nil && isBranchTrackingError(pullErr) {
		if err := schema.DrainCall(ctx, tx, "CALL DOLT_FETCH(?, ?)", remote, s.branch); err != nil {
			_ = tx.Rollback()
			return pullReport{}, fmt.Errorf("fetch from %s/%s: %w", remote, s.branch, err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the pull — transient connection drops are the most common cause
  2. Check the wrapped cause: if 'unknown variable', upgrade Dolt to a version supporting dolt_force_transaction_commit
  3. Verify the Dolt server is reachable and not restarting (check server logs)
  4. Increase the context timeout for the pull operation

Example fix

// before
if _, err := tx.ExecContext(ctx, "SET @@dolt_force_transaction_commit = 1"); err != nil {
    _ = tx.Rollback()
    return pullReport{}, fmt.Errorf("failed to set dolt_force_transaction_commit: %w", err)
}
// after
ctx, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()
if _, err := tx.ExecContext(ctx, "SET @@dolt_force_transaction_commit = 1"); err != nil {
    _ = tx.Rollback()
    return pullReport{}, fmt.Errorf("failed to set dolt_force_transaction_commit: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Before pulling, confirm the Dolt engine supports the session variable
rows, err := db.Query("SELECT @@dolt_force_transaction_commit IS NOT NULL")
if err != nil {
    // 'unknown variable' => upgrade Dolt before pulling
}

Try / catch

var pullErr error
for attempt := 0; attempt < 3; attempt++ {
    pullErr = store.Pull(ctx)
    if pullErr == nil || !strings.Contains(pullErr.Error(), "dolt_force_transaction_commit") {
        break
    }
    time.Sleep(time.Duration(attempt+1) * time.Second)
}

Prevention

When it happens

Trigger: During DoltStore pull operations that execute `SET @@dolt_force_transaction_commit = 1` via tx.ExecContext and the statement returns an error — e.g. the connection dropped mid-pull, the Dolt server rejected the session variable, or a context timeout canceled the query.

Common situations: Dolt server restarts or connection resets during `bd dolt pull`; an old Dolt engine version that does not recognize dolt_force_transaction_commit; context deadline exceeded on a slow pull against a large remote.

Related errors


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