gastownhall/beads · error
remaining blocker rows from %s: %w
Error message
remaining blocker rows from %s: %w
What it means
Wraps an error from depRows.Err() after iterating the remaining-blocker result set in GetNewlyUnblockedByCloseInTx. This catches errors that surfaced asynchronously during row streaming (connection drop, driver I/O failure) rather than at query or scan time. It fails the unblock computation to avoid returning a partially computed result.
Source
Thrown at internal/storage/issueops/dependency_queries.go:863
`, DepTargetExpr, depTable, placeholders, DepTargetExpr), append(batchArgs, closedIssueID)...)
if err != nil {
if optionalBlockedTable(depTable) && isTableNotExistError(err) {
continue
}
return nil, fmt.Errorf("check remaining blockers from %s: %w", depTable, err)
}
for depRows.Next() {
var candidateID, blockerID string
if err := depRows.Scan(&candidateID, &blockerID); err != nil {
_ = depRows.Close()
return nil, fmt.Errorf("scan remaining blocker: %w", err)
}
remainingByCandidate[candidateID] = append(remainingByCandidate[candidateID], blockerID)
remainingBlockerSet[blockerID] = struct{}{}
}
_ = depRows.Close()
if err := depRows.Err(); err != nil {
return nil, fmt.Errorf("remaining blocker rows from %s: %w", depTable, err)
}
}
remainingBlockerIDs := make([]string, 0, len(remainingBlockerSet))
for blockerID := range remainingBlockerSet {
remainingBlockerIDs = append(remainingBlockerIDs, blockerID)
}
sort.Strings(remainingBlockerIDs)
statusByID, err := loadStatusByIDInTx(ctx, tx, remainingBlockerIDs)
if err != nil {
return nil, fmt.Errorf("check remaining blocker status: %w", err)
}
for candidateID, blockerIDs := range remainingByCandidate {
for _, blockerID := range blockerIDs {
status, ok := statusByID[blockerID]
if ok && status != types.StatusClosed && status != types.StatusPinned {
stillBlocked[candidateID] = true
breakView on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped error for connection/context details
- If it is context cancellation, raise the timeout or avoid cancelling mid-transaction
- For network drivers, verify server connectivity and retry the transaction
- For embedded storage, check for file locks/corruption and repair
Defensive patterns
Strategy: try-catch
Try / catch
if err := tx.CloseIssue(ctx, id); err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
// retry with a longer-lived context
}
return err
} Prevention
- Use generous timeouts for close/unblock operations
- Avoid suspending machines or killing processes mid-transaction
- For remote Dolt servers, monitor connection stability
When it happens
Trigger: The underlying connection or driver encounters an I/O or protocol error while streaming rows from a dependency table, detected only after the loop finishes via rows.Err().
Common situations: Embedded DB file locked or disconnected mid-query; network interruption to a remote Dolt SQL server; context cancellation during long iteration.
Related errors
- iterate inbound dependencies from %s: %w
- blocker edge rows from %s: %w
- check issue existence in %s: rows: %w
- row iteration error: %w
- count wisp dependencies: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/80bef8d5cd9bf618.
Report an issue: GitHub.