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

  1. Check the wrapped cause: if it is context.DeadlineExceeded/Canceled, increase the command's timeout or rerun without cancellation.
  2. Ensure the store is still open — do not call merge/pull methods after Close(); in tests, defer close until after assertions.
  3. Retry the operation once the engine is healthy; transient pool exhaustion clears when concurrent operations finish.
  4. If the database itself failed to open (corruption), run `bd doctor` and restore/re-initialize the embedded database.
  5. 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

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


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