gastownhall/beads · critical
acquire connection after SQL mutation: %w: %w
Error message
acquire connection after SQL mutation: %w: %w
What it means
In commitWorkingSetAfterSQLCommit, acquiring a connection after a SQL mutation failed. Because a mutation already succeeded but the commit did not run, the error is wrapped with ErrCommitIndeterminate — the commit outcome is unknown and must not be blindly retried.
Source
Thrown at internal/storage/dolt/store.go:3291
}
// doltAddAndCommit stages the specified tables and commits on a pinned
// connection. This prevents DOLT_COMMIT('-Am') from sweeping up stale
// working set changes from concurrent operations (GH#2455). Every caller has
// already committed its SQL mutation, so any publication failure here has an
// indeterminate durable outcome and must not be replayed.
func (s *DoltStore) doltAddAndCommit(ctx context.Context, tables []string, commitMsg string) error {
// Batch/off auto-commit (bd-4wamg): leave the writes in the working set
// for a later explicit commit point (bd dolt commit / CommitPending),
// matching doltAddAndCommitInTx.
if issueops.VersionCommitDeferred(ctx) {
return nil
}
return s.withCircuitWrite(ctx, func(ctx context.Context) error {
conn, err := s.db.Conn(ctx)
if err != nil {
return s.recordDoltPublicationFailure(ctx,
fmt.Errorf("acquire connection after SQL mutation: %w: %w", err, ErrCommitIndeterminate))
}
defer conn.Close()
for _, table := range tables {
if err := schema.DrainCall(ctx, conn, "CALL DOLT_ADD(?)", table); err != nil {
return s.recordDoltPublicationFailure(ctx,
fmt.Errorf("dolt add %s after SQL mutation: %w: %w", table, err, ErrCommitIndeterminate))
}
}
// Skip the commit when nothing was actually staged (idempotent no-op
// write), so Dolt does not log a server-side "nothing to commit" warning
// on every reconcile-cadence call. The guard tests the STAGED set rather
// than the whole working set because this helper stages only a fixed
// table list — an unrelated dirty table must not trigger an empty '-m'
// commit. A guard-read failure is NOT a publication failure: nothing has
// been committed and nothing is indeterminate, so plain error return.
staged, err := issueops.HasStagedChanges(ctx, conn)View on GitHub (pinned to 71377f2769)
Solutions
- Treat the commit as indeterminate: run `bd dolt status` / `bd dolt log` to check whether the commit landed before retrying.
- Restore Dolt server connectivity, then re-run the operation; the code path is idempotent for uncommitted staged changes.
- If the commit did land, do nothing further; if not, re-trigger the operation to publish.
- Check server logs for crash/restart at that timestamp.
Defensive patterns
Strategy: try-catch
Validate before calling
// check server reachability before mutations that require publication
if err := s.db.PingContext(ctx); err != nil {
return fmt.Errorf("skip mutation: publication path unavailable: %w", err)
} Try / catch
if errors.Is(err, ErrCommitIndeterminate) {
// verify with `bd dolt log` / `bd dolt status` whether the commit landed
// before re-triggering the operation
} Prevention
- Never blind-retry operations wrapped with ErrCommitIndeterminate; check dolt log first.
- Keep the Dolt server on stable infrastructure with health checks.
- Avoid network partitions between bd and a server-mode Dolt.
- Ensure connection pool headroom before write-heavy operations.
When it happens
Trigger: The store attempts to dolt-add/commit tables after a raw SQL mutation (doltAddAndCommit path) and s.db.Conn(ctx) fails because the server became unreachable or the pool drained at exactly that moment.
Common situations: Dolt server crash or network drop between the SQL write and the publication commit; connection-pool exhaustion under heavy concurrent agent load.
Related errors
- dolt server connection failed: %w
- failed to reach the workspace identity: %v
- begin tx: %w
- begin read tx: %w
- begin write tx: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/26ddfaa89921130d.
Report an issue: GitHub.