gastownhall/beads · error
embeddeddolt: pin connection: %w
Error message
embeddeddolt: pin connection: %w
What it means
withPinnedDBConn could not obtain a dedicated connection from the embedded Dolt SQL database (db.Conn(ctx) failed), which is required to run the caller's function against one pinned connection. The pool could not hand out a connection — typically because the context was cancelled, the database is closed, or the pool is exhausted/broken. The error is wrapped with the embeddeddolt prefix so the underlying driver cause is preserved.
Source
Thrown at internal/storage/embeddeddolt/version_control.go:73
return errClosed
}
var db *sql.DB
var cleanup func() error
db, cleanup, err = OpenSQL(ctx, s.dataDir, s.database, s.branch)
if err != nil {
return
}
defer func() {
err = errors.Join(err, cleanup())
// Best-effort cleanup of orphaned tmp_pack_* files left by git
// fetch in the Dolt git-remote-cache. Rate-limited internally.
s.cleanGitRemoteCacheGarbage()
}()
conn, connErr := db.Conn(ctx)
if connErr != nil {
return fmt.Errorf("embeddeddolt: pin connection: %w", connErr)
}
defer conn.Close()
return fn(conn)
}
// withMutatingDBConn is withDBConn for operations that mutate the database
// or its version-control state (merge, push/pull, branch ops, backups, GC).
// withDBConn runs outside any SQL transaction, so withConn's commit guard
// never sees these — a read-only store satisfies the full DoltStorage
// interface and must refuse them here instead (bd-578h9.12).
func (s *EmbeddedDoltStore) withMutatingDBConn(ctx context.Context, fn func(db versioncontrolops.DBConn) error) error {
if s.readOnly {
return ErrReadOnly
}
return s.withDBConn(ctx, fn)
}
View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped cause: if it is context.DeadlineExceeded/Canceled, increase the command's timeout or rerun without cancellation.
- Ensure the store is still open — do not call merge/pull methods after Close(); in tests, defer close until after assertions.
- Retry the operation once the engine is healthy; transient pool exhaustion clears when concurrent operations finish.
- If the database itself failed to open (corruption), run `bd doctor` and restore/re-initialize the embedded database.
- Serialize heavy VC operations (merge/pull/push) rather than running them concurrently against the same embedded store.
Example fix
// before: assuming the store is always usable
err := store.Merge(ctx, branch, author)
// after: guard context and store lifecycle
if store.Closed() {
return errors.New("store closed")
}
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()
err := store.Merge(ctx, branch, author) Defensive patterns
Strategy: retry
Validate before calling
if store.Closed() { // guard lifecycle before pinned-conn operations
return errors.New("store already closed")
}
if err := ctx.Err(); err != nil {
return fmt.Errorf("context already done: %w", err)
} Try / catch
if err := store.Merge(ctx, branch, author); err != nil {
if strings.Contains(err.Error(), "pin connection") {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
// retry with a fresh, longer-lived context
}
// otherwise: store closed or engine unhealthy — do not retry blindly
}
return err
} Prevention
- Keep contexts alive long enough for merge/pull operations; check ctx.Err() before long VC commands.
- Never call store methods after Close(); in tests, close only after all assertions.
- Avoid running many concurrent VC operations against one embedded store.
- Re-initialize the store cleanly if the engine failed to open instead of reusing the broken instance.
When it happens
Trigger: Calling any path that goes through withMutatingPinnedDBConn (pinned-connection merge/pull/commit helpers) when the embedded SQL engine has been closed, when ctx is cancelled before the connection is acquired, or when the underlying driver cannot create a connection (corrupt database, resource exhaustion).
Common situations: A long-running `bd` command whose context deadline expired just before a pinned-connection operation; calling store methods after Close(); running operations concurrently beyond what the embedded engine tolerates; startup failures where the Dolt engine never initialized.
Related errors
- no database connection available (%s)
- dolt server unreachable at %s:%d (is dolt sql-server running
- failed to open server connection: %w
- server not reachable: %w
- dolt server connection failed: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/05feaf34d1cdb396.
Report an issue: GitHub.