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
- Ensure no stuck bd process is holding pooled connections (check Dolt processlist)
- Retry — pool exhaustion is usually transient
- Increase the pool size or reduce concurrent long-running queries
- Check Dolt server availability and connection limits
- 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
- Avoid running many long bd commands concurrently
- Size the connection pool for peak concurrency
- Use adequate context timeouts for recomputes on large databases
- Watch for leaked/stuck transactions holding pool slots
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- pull succeeded but is_blocked recompute failed: %w
- conflicts resolved but is_blocked recompute failed: %w
- iter dependents: acquire conn: %w
- checkout active branch %q: %w
- failed to rebuild pool after migration: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c7b87d01ffd36caa.
Report an issue: GitHub.