gastownhall/beads · error

acquire long-timeout connection: %w

Error message

acquire long-timeout connection: %w

What it means

Thrown when acquiring a dedicated physical connection (db.Conn) for the full-recompute pass fails. The recompute needs one pinned connection so the long-timeout session variable and branch pinning apply consistently; failing to get that connection aborts the recompute with a count of 0.

Source

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

	// recompute never lands (bd-bn8jo). Run it on a dedicated long-timeout
	// connection like the other known-long maintenance ops.
	db, err := s.openLongTimeoutConn()
	if err != nil {
		return 0, err
	}
	defer db.Close()
	// Pin a single physical connection for the whole operation (same
	// pattern as federation.go's filteredPushToPeer — branch state is
	// connection-scoped, so BeginTx must run on the exact connection that
	// was just checked out, not whatever the pool hands out next) and
	// reproduce the store's real active branch on it before the recompute
	// reads or writes anything; otherwise this fresh connection defaults to
	// Dolt's default branch instead of whatever the store is actually
	// checked out to (be-b0am).
	db.SetMaxIdleConns(0)
	conn, err := db.Conn(ctx)
	if err != nil {
		return 0, fmt.Errorf("acquire long-timeout connection: %w", err)
	}
	defer conn.Close()
	if err := s.pinStoreBranch(ctx, conn); err != nil {
		return 0, err
	}
	return s.recomputeAllBlockedWithDB(ctx, conn)
}

// txBeginner is satisfied by both *sql.DB and *sql.Conn, letting
// recomputeAllBlockedWithDB run either against a caller-owned pinned
// *sql.Conn (recomputeAllBlocked) or directly against a *sql.DB (tests).
type txBeginner interface {
	BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
}

func (s *DoltStore) recomputeAllBlockedWithDB(ctx context.Context, db txBeginner) (int, error) {
	tx, err := db.BeginTx(ctx, nil)
	if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure no stuck bd process is holding pooled connections (check Dolt processlist)
  2. Retry — pool exhaustion is usually transient
  3. Increase the pool size or reduce concurrent long-running queries
  4. Check Dolt server availability and connection limits
  5. Raise the context timeout for the recompute call
Defensive patterns

Strategy: retry

Validate before calling

// Check the server accepts connections before a long recompute
if err := db.PingContext(ctx); err != nil {
    return fmt.Errorf("dolt unavailable: %w", err)
}

Try / catch

n, err := store.RecomputeAllBlocked(ctx)
if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "acquire long-timeout connection") {
    // retry with a longer timeout
    ctx2, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
    defer cancel()
    n, err = store.RecomputeAllBlocked(ctx2)
}

Prevention

When it happens

Trigger: Calling the recompute-all-blocked entry point when the database pool cannot hand out a connection: pool exhausted by other long-running transactions, context canceled/timed out while waiting for a connection, or the Dolt server is down.

Common situations: Many concurrent bd commands holding pooled connections; a stuck transaction leaking connections; Dolt server restart; context deadline too short under load.

Understand the failure class

Related errors


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