gastownhall/beads · error

acquire connection for remote-ref prune: %w

Error message

acquire connection for remote-ref prune: %w

What it means

PruneRemoteRefs pins a single connection before delegating to versioncontrolops.PruneRemoteRefs (used after squash so GC can reclaim anchored history); this error wraps db.Conn(ctx) failing to hand out that connection. No refs have been pruned; it is a pool-acquisition failure.

Source

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

	conn, err := s.db.Conn(ctx)
	if err != nil {
		return fmt.Errorf("acquire connection for gc: %w", err)
	}
	defer conn.Close()
	return versioncontrolops.DoltGC(ctx, conn)
}

// ListRemoteRefs returns the names of all cached remote-tracking refs.
func (s *DoltStore) ListRemoteRefs(ctx context.Context) ([]string, error) {
	return versioncontrolops.ListRemoteRefs(ctx, s.db)
}

// PruneRemoteRefs deletes all cached remote-tracking refs so a post-squash GC
// can reclaim the history they anchor (bd-agctw). Returns the deleted names.
func (s *DoltStore) PruneRemoteRefs(ctx context.Context) ([]string, error) {
	conn, err := s.db.Conn(ctx)
	if err != nil {
		return nil, fmt.Errorf("acquire connection for remote-ref prune: %w", err)
	}
	defer conn.Close()
	return versioncontrolops.PruneRemoteRefs(ctx, conn)
}

// ListTags returns the names of all Dolt tags.
func (s *DoltStore) ListTags(ctx context.Context) ([]string, error) {
	return versioncontrolops.ListTags(ctx, s.db)
}

// Flatten squashes all Dolt commit history into a single commit.
// Pins a single connection because the stored procedures (DOLT_CHECKOUT,
// DOLT_RESET, etc.) rely on session-scoped state that would be lost if
// steps execute on different pooled connections.
func (s *DoltStore) Flatten(ctx context.Context) error {
	conn, err := s.db.Conn(ctx)
	if err != nil {
		return fmt.Errorf("acquire connection for flatten: %w", err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry PruneRemoteRefs after load subsides; schedule remote-ref pruning in maintenance windows
  2. Raise the ctx timeout for the call
  3. Verify the Dolt server is reachable and the pool is healthy (PingContext) before pruning
  4. Check wrapped error class: dial failure → connectivity/DSN; deadline → timeout/pool saturation

Example fix

// before
deleted, err := store.PruneRemoteRefs(ctx)
// after
pCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
deleted, err := store.PruneRemoteRefs(pCtx)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) { /* connectivity path */ }
}
Defensive patterns

Strategy: retry

Validate before calling

// verify server reachability before pruning refs
if err := s.db.PingContext(ctx); err != nil {
    return nil, fmt.Errorf("skip remote-ref prune, server unreachable: %w", err)
}

Try / catch

// Go: backoff-retry transient acquisition errors
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, driver.ErrBadConn) {
        // safe to retry: no refs were pruned
        return retryPrune(ctx)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling PruneRemoteRefs(ctx) when the pool cannot supply a connection: ctx deadline/cancel while waiting, pool saturated with busy connections, server down so dialing a new pooled connection fails, driver ErrBadConn.

Common situations: Post-squash maintenance run while the app is under load; shutdown hook with a canceled context; Dolt server outage; stale pool after server restart.

Related errors


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