gastownhall/beads · error

get dependency counts: blocker rows: %w

Error message

get dependency counts: blocker rows: %w

What it means

Returned by GetDependencyCountsInTx after iterating the 'blocked-by counts' result set when rows.Err() reports that the underlying driver encountered an error mid-iteration (network drop, query cancellation, driver failure). The rows were being read fine, but the connection or query failed before the result set was exhausted.

Source

Thrown at internal/storage/issueops/dependency_queries.go:489

				if optionalBlockedTable(depTable) && isTableNotExistError(err) {
					continue
				}
				return nil, fmt.Errorf("get dependency counts (blockers from %s): %w", depTable, err)
			}
			for depRows.Next() {
				var id string
				var cnt int
				if err := depRows.Scan(&id, &cnt); err != nil {
					_ = depRows.Close()
					return nil, fmt.Errorf("get dependency counts: scan blocker: %w", err)
				}
				if c, ok := result[id]; ok {
					c.DependencyCount += cnt
				}
			}
			_ = depRows.Close()
			if err := depRows.Err(); err != nil {
				return nil, fmt.Errorf("get dependency counts: blocker rows: %w", err)
			}

			//nolint:gosec // G201: depTable is hardcoded and inClause contains only ? placeholders.
			blockingRows, err := tx.QueryContext(ctx, fmt.Sprintf(`
				SELECT %s AS depends_on_id, COUNT(*) as cnt
				FROM %s
				WHERE %s AND type = 'blocks'
				GROUP BY %s
			`, DepTargetExpr, depTable, depTargetIn("", inClause), DepTargetExpr), args...)
			if err != nil {
				if optionalBlockedTable(depTable) && isTableNotExistError(err) {
					continue
				}
				return nil, fmt.Errorf("get dependency counts (dependents from %s): %w", depTable, err)
			}
			for blockingRows.Next() {
				var id string
				var cnt int

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped error: if it is context deadline/cancel, increase the timeout or reduce work per call.
  2. Retry the operation — transient network errors to remote backends often resolve on re-run.
  3. Reduce batch pressure by calling with fewer issue IDs per invocation (results are batched by queryBatchSize internally).
  4. Check remote Dolt server health/logs for connection resets and restart or fix the server.
  5. If persistent, switch to a local embedded Dolt database or improve network stability to the remote.

Example fix

// before: single call over hundreds of IDs on a flaky remote
counts, err := GetDependencyCountsInTx(ctx, tx, allIDs)

// after: chunk the input and retry transient failures
counts := map[string]*types.DependencyCounts{}
for _, chunk := range chunkIDs(allIDs, 100) {
    c, err := GetDependencyCountsInTx(ctx, tx, chunk)
    if isTransient(err) {
        c, err = retry(3, func() (map[string]*types.DependencyCounts, error) {
            return GetDependencyCountsInTx(ctx, tx, chunk)
        })
    }
    if err != nil { return nil, err }
    for k, v := range c { counts[k] = v }
}
Defensive patterns

Strategy: retry

Validate before calling

// Go: probe connection health before the call
if err := tx.QueryRowContext(ctx, "SELECT 1").Err(); err != nil {
    return fmt.Errorf("database unavailable: %w", err)
}

Type guard

func isTransientRowsError(err error) bool {
    if err == nil { return false }
    msg := err.Error()
    return strings.Contains(msg, "blocker rows") ||
        errors.Is(err, context.DeadlineExceeded) ||
        errors.Is(err, context.Canceled) ||
        strings.Contains(msg, "connection refused") ||
        strings.Contains(msg, "driver: bad connection")
}

Try / catch

counts, err := GetDependencyCountsInTx(ctx, tx, ids)
if isTransientRowsError(err) {
    select {
    case <-time.After(backoff):
        counts, err = GetDependencyCountsInTx(ctx, tx, ids)
    case <-ctx.Done():
        return ctx.Err()
    }
}

Prevention

When it happens

Trigger: Calling GetDependencyCountsInTx (via HydrateReadyRowInTx) when the database connection drops or the context is cancelled while streaming GROUP BY results from dependencies/wisp_dependencies; remote Dolt server closing the connection mid-response.

Common situations: Flaky network to a remote Dolt backend; server-side timeouts on large IN batches; context deadline exceeded during a slow query; Dolt server restart during a long bd operation.

Related errors


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