{"record":{"id":"4ffcf5af68043206","repo":"gastownhall/beads","slug":"get-blocking-info-blocked-by-rows-w","errorCode":null,"errorMessage":"get blocking info: blocked-by rows: %w","messagePattern":"get blocking info: blocked-by rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":634,"sourceCode":"\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"get blocked-by info from %s: %w\", depTable, err)\n\t\t}\n\t\tvar depRows []blockingInfoRow\n\t\tvar blockerIDs []string\n\t\tfor rows.Next() {\n\t\t\tvar row blockingInfoRow\n\t\t\tif scanErr := rows.Scan(&row.issueID, &row.blockerID, &row.depType); scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"get blocking info: scan blocked-by: %w\", scanErr)\n\t\t\t}\n\t\t\tdepRows = append(depRows, row)\n\t\t\tblockerIDs = append(blockerIDs, row.blockerID)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"get blocking info: blocked-by rows: %w\", err)\n\t\t}\n\n\t\tstatusByID, err := loadStatusByIDInTx(ctx, tx, blockerIDs)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get blocking info: blocker status: %w\", err)\n\t\t}\n\t\tfor _, row := range depRows {\n\t\t\tif statusByID[row.blockerID] == types.StatusClosed {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif row.depType == \"parent-child\" {\n\t\t\t\tparentMap[row.issueID] = row.blockerID\n\t\t\t} else {\n\t\t\t\tblockedByMap[row.issueID] = append(blockedByMap[row.issueID], row.blockerID)\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L616-L652","documentation":"Returned by queryBlockedByInfo when rows.Err() reports a driver failure after iterating the blocked-by result set — the connection or query failed mid-stream rather than any individual row failing to scan.","triggerScenarios":"Calling GetBlockingInfoForIssuesInTx when the database connection drops, the context is cancelled, or the remote Dolt server errors while the blocked-by rows are being streamed.","commonSituations":"Flaky network to remote Dolt; context deadlines on large batches; server restarts or idle-connection kills by proxies during bd operations.","solutions":["Read the wrapped error: for context deadline/cancellation, increase timeouts or shrink input batches.","Retry the operation; transient stream errors usually resolve.","Check remote Dolt server health and logs; restart if it reset connections.","Reduce the number of issue IDs per call to shorten result streams.","Raise proxy/LB idle timeouts if long queries are being cut off."],"exampleFix":"// before: unbounded context on a slow remote\ninfo, err := GetBlockingInfoForIssuesInTx(ctx, tx, manyIDs)\n\n// after: explicit timeout with retry\nctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\ninfo, err := GetBlockingInfoForIssuesInTx(ctx, tx, manyIDs)\nif err != nil && isTransient(err) {\n    info, err = GetBlockingInfoForIssuesInTx(ctx, tx, manyIDs) // retry\n}","handlingStrategy":"retry","validationCode":"// Go: fail fast if the connection is already dead\nif err := tx.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"skipping blocked-by query, DB unreachable: %w\", err)\n}","typeGuard":"func isBlockedByRowsError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"blocked-by rows\")\n}","tryCatchPattern":"blockedBy, blocks, parents, err := GetBlockingInfoForIssuesInTx(ctx, tx, ids)\nif isBlockedByRowsError(err) && errors.Is(err, context.DeadlineExceeded) {\n    ctx2, cancel := context.WithTimeout(context.Background(), longerTimeout)\n    defer cancel()\n    blockedBy, blocks, parents, err = GetBlockingInfoForIssuesInTx(ctx2, tx, ids)\n}","preventionTips":["Use contexts with adequate deadlines for remote backends.","Keep batch sizes moderate to keep result streams short.","Enable TCP keepalives on the DB connection.","Retry transient errors with jittered exponential backoff.","Monitor server logs for mid-query disconnects."],"tags":["database","network","row-iteration","context-cancelled"],"backgroundTag":"database-connection-dropped","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}