{"record":{"id":"f06d17ed94fa67d9","repo":"gastownhall/beads","slug":"get-dependency-counts-dependent-rows-w","errorCode":null,"errorMessage":"get dependency counts: dependent rows: %w","messagePattern":"get dependency counts: dependent rows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":518,"sourceCode":"\t\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts (dependents from %s): %w\", depTable, err)\n\t\t\t}\n\t\t\tfor blockingRows.Next() {\n\t\t\t\tvar id string\n\t\t\t\tvar cnt int\n\t\t\t\tif err := blockingRows.Scan(&id, &cnt); err != nil {\n\t\t\t\t\t_ = blockingRows.Close()\n\t\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts: scan dependent: %w\", err)\n\t\t\t\t}\n\t\t\t\tif c, ok := result[id]; ok {\n\t\t\t\t\tc.DependentCount += cnt\n\t\t\t\t}\n\t\t\t}\n\t\t\t_ = blockingRows.Close()\n\t\t\tif err := blockingRows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts: dependent rows: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\n// GetBlockingInfoForIssuesInTx returns blocking dependency records for a set of issue IDs.\n// Returns three maps:\n//   - blockedByMap: issueID -> list of IDs blocking it\n//   - blocksMap: issueID -> list of IDs it blocks\n//   - parentMap: childID -> parentID (parent-child deps)\nfunc GetBlockingInfoForIssuesInTx(ctx context.Context, tx DBTX, issueIDs []string) (\n\tblockedByMap map[string][]string,\n\tblocksMap map[string][]string,\n\tparentMap map[string]string,\n\terr error,\n) {","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L500-L536","documentation":"Returned by GetDependencyCountsInTx after finishing iteration of the 'dependents counts' result set when rows.Err() reports a driver-level failure during iteration (connection loss, cancellation, server error). Equivalent to the blocker-rows variant but on the inbound (dependents) query.","triggerScenarios":"Calling GetDependencyCountsInTx when the database connection drops or the context is cancelled while streaming dependents counts from dependencies/wisp_dependencies, or the remote Dolt server fails mid-response.","commonSituations":"Network interruptions to remote backends; context deadlines on slow queries; Dolt server restarts; TLS/proxy idle timeouts cutting off long result streams.","solutions":["Check the wrapped error: context cancellation means raise the timeout or reduce per-call work.","Retry the call — iteration errors from transient network issues usually clear on re-run.","Verify connectivity to the remote Dolt server (ping, server logs) and restart if it crashed.","Split large ID lists into smaller calls to shorten each streamed result.","If behind a proxy/LB, raise its idle timeout for long-running queries."],"exampleFix":"// before: one giant call over a flaky link\nresult, err := GetDependencyCountsInTx(ctx, tx, thousandsOfIDs)\n\n// after: bounded timeout + retry per chunk\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\nfor _, chunk := range chunkIDs(thousandsOfIDs, 100) {\n    if _, err := GetDependencyCountsInTx(ctx, tx, chunk); err != nil {\n        if !isTransient(err) { return err }\n        time.Sleep(backoff) // then retry chunk\n    }\n}","handlingStrategy":"retry","validationCode":"// Go: check context and connectivity before the call\nif ctx.Err() != nil {\n    return ctx.Err()\n}\nif err := tx.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":"func isDependentRowsError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"dependent rows\")\n}","tryCatchPattern":"counts, err := GetDependencyCountsInTx(ctx, tx, ids)\nif isDependentRowsError(err) && isRetryable(err) {\n    time.Sleep(exponentialBackoff(attempt))\n    counts, err = GetDependencyCountsInTx(ctx, tx, ids)\n}","preventionTips":["Set generous context timeouts for remote Dolt operations.","Split very large ID sets into smaller calls.","Use connection pools with health checks (ConnMaxLifetime, idle pings).","Watch for proxy/LB idle timeouts and raise them for DB traffic.","Alert on remote server restarts to correlate with iteration errors."],"tags":["database","network","row-iteration","timeout"],"backgroundTag":"database-connection-dropped","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}