gastownhall/beads · error
acquire connection for gc: %w
Error message
acquire connection for gc: %w
What it means
DoltGC pins a single pooled connection before delegating to versioncontrolops.DoltGC, because GC depends on session state that pooled connections would lose; this error wraps failure to acquire that connection from the *sql.DB pool. The actual GC has not started — this is purely pool-acquisition failure.
Source
Thrown at internal/storage/dolt/store.go:2877
if s.localActiveDatabaseDir == "" {
return 0, &storage.ErrUnsupported{
Op: "ActiveDatabaseSize",
Backend: "dolt-server",
}
}
size, err := storage.MeasureDirectorySize(ctx, s.localActiveDatabaseDir)
if err != nil {
return 0, fmt.Errorf("measure active database directory %q: %w", s.localActiveDatabaseDir, err)
}
return size, nil
}
// DoltGC runs Dolt garbage collection to reclaim disk space.
// Pins a single connection to avoid session state loss on pooled *sql.DB.
func (s *DoltStore) DoltGC(ctx context.Context) error {
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()View on GitHub (pinned to 71377f2769)
Solutions
- Retry DoltGC when the pool is less loaded; run GC during quiet periods
- Check the wrapped error: context.DeadlineExceeded → raise timeout; dial errors → verify server up and DSN correct
- Avoid holding many long transactions concurrently with GC calls
- Ensure ctx passed to DoltGC has adequate timeout
Example fix
// before err := store.DoltGC(ctx) // caller's short ctx // after gcCtx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) defer cancel() err := store.DoltGC(gcCtx)
Defensive patterns
Strategy: retry
Validate before calling
// ensure pool is healthy before GC
if err := store.PingContext(ctx); err != nil {
return fmt.Errorf("skip GC, server unreachable: %w", err)
} Try / catch
// Go: retry pool acquisition with backoff
var lastErr error
for i := 0; i < 3; i++ {
if err := store.DoltGC(ctx); err == nil {
break
} else if errors.Is(err, context.DeadlineExceeded) {
lastErr = err
time.Sleep(time.Duration(1<<i) * time.Second)
continue
}
return err
} Prevention
- Run GC in maintenance windows with low pool contention
- Pass a long-timeout context to GC (it can be slow)
- Avoid canceling ctx during shutdown before GC finishes
- Ping the server before scheduled GC runs
When it happens
Trigger: Calling DoltGC(ctx) when db.Conn(ctx) fails: ctx canceled/timed out while waiting for a free connection, pool exhausted by long-running queries, server unreachable so new dial fails, driver ErrBadConn loop.
Common situations: Running GC concurrently with heavy workload saturating the pool; application shutdown canceling ctx; Dolt server restarted; network partition.
Related errors
- acquire connection for remote-ref prune: %w
- acquire connection for flatten: %w
- acquire connection for compact: %w
- failed to acquire connection: %w
- ErrTransaction
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/18651f8f5d689b21.
Report an issue: GitHub.