{"record":{"id":"c7b87d01ffd36caa","repo":"gastownhall/beads","slug":"acquire-long-timeout-connection-w","errorCode":null,"errorMessage":"acquire long-timeout connection: %w","messagePattern":"acquire long-timeout connection: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":4570,"sourceCode":"\t// recompute never lands (bd-bn8jo). Run it on a dedicated long-timeout\n\t// connection like the other known-long maintenance ops.\n\tdb, err := s.openLongTimeoutConn()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer db.Close()\n\t// Pin a single physical connection for the whole operation (same\n\t// pattern as federation.go's filteredPushToPeer — branch state is\n\t// connection-scoped, so BeginTx must run on the exact connection that\n\t// was just checked out, not whatever the pool hands out next) and\n\t// reproduce the store's real active branch on it before the recompute\n\t// reads or writes anything; otherwise this fresh connection defaults to\n\t// Dolt's default branch instead of whatever the store is actually\n\t// checked out to (be-b0am).\n\tdb.SetMaxIdleConns(0)\n\tconn, err := db.Conn(ctx)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"acquire long-timeout connection: %w\", err)\n\t}\n\tdefer conn.Close()\n\tif err := s.pinStoreBranch(ctx, conn); err != nil {\n\t\treturn 0, err\n\t}\n\treturn s.recomputeAllBlockedWithDB(ctx, conn)\n}\n\n// txBeginner is satisfied by both *sql.DB and *sql.Conn, letting\n// recomputeAllBlockedWithDB run either against a caller-owned pinned\n// *sql.Conn (recomputeAllBlocked) or directly against a *sql.DB (tests).\ntype txBeginner interface {\n\tBeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)\n}\n\nfunc (s *DoltStore) recomputeAllBlockedWithDB(ctx context.Context, db txBeginner) (int, error) {\n\ttx, err := db.BeginTx(ctx, nil)\n\tif err != nil {","sourceCodeStart":4552,"sourceCodeEnd":4588,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L4552-L4588","documentation":"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.","triggerScenarios":"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.","commonSituations":"Many concurrent bd commands holding pooled connections; a stuck transaction leaking connections; Dolt server restart; context deadline too short under load.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Check the server accepts connections before a long recompute\nif err := db.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"dolt unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"n, err := store.RecomputeAllBlocked(ctx)\nif errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), \"acquire long-timeout connection\") {\n    // retry with a longer timeout\n    ctx2, cancel := context.WithTimeout(context.Background(), 10*time.Minute)\n    defer cancel()\n    n, err = store.RecomputeAllBlocked(ctx2)\n}","preventionTips":["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"],"tags":["dolt","connection-pool","recompute"],"backgroundTag":"connection-pool-exhausted","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}