gastownhall/beads · error

iterate neighbors from %s: %w

Error message

iterate neighbors from %s: %w

What it means

After the neighbor-iteration loop, rows.Err() reported a deferred failure from the result stream — the classic pattern for a connection drop or cancellation that only surfaces once rows are exhausted. The wrapper names the dependency table whose iteration failed. The whole delete (including the pending deletion in this transaction) aborts and rolls back.

Source

Thrown at internal/storage/issueops/delete_role.go:289

				}
				return nil, fmt.Errorf("query neighbors from %s: %w", depTable, err)
			}
			for rows.Next() {
				var source, target string
				if err := rows.Scan(&source, &target); err != nil {
					_ = rows.Close()
					return nil, fmt.Errorf("scan neighbor: %w", err)
				}
				for _, candidate := range [2]string{source, target} {
					if candidate == "" || deleting[candidate] {
						continue
					}
					neighborIDs[candidate] = true
				}
			}
			_ = rows.Close()
			if err := rows.Err(); err != nil {
				return nil, fmt.Errorf("iterate neighbors from %s: %w", depTable, err)
			}
		}
	}
	if len(neighborIDs) == 0 {
		return nil, nil
	}

	// Sorted so the rewrite touches rows in a stable order, which is what
	// makes a partially-applied failure reproducible.
	hydrate := workapi.SortedDeleteIDs(neighborIDs)
	// An `external:` target and a target belonging to another repository name
	// no row here; GetIssuesByIDsInTx simply does not return them.
	issues, err := GetIssuesByIDsInTx(ctx, tx, hydrate, nil)
	if err != nil {
		return nil, fmt.Errorf("hydrate neighbors: %w", err)
	}
	return issues, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the delete in a fresh transaction; it is safe — nothing committed
  2. Increase the context timeout for large cascades
  3. Check server logs for aborted queries and network stability
  4. Split very large deletes into smaller batches to shrink each result stream
Defensive patterns

Strategy: retry

Validate before calling

if err := ctx.Err(); err != nil { return err }

Try / catch

err := store.Delete(ctx, req)
if err != nil && strings.Contains(err.Error(), "iterate neighbors from") {
    // deferred rows.Err() mid-stream; whole tx rolled back, retry safely
    return retryDelete(req, longerTimeout)
}

Prevention

When it happens

Trigger: deleteNeighborsInTx closes rows after scanning neighbors from dependencies/wisp_dependencies and rows.Err() is non-nil — network interruption, server abort, or context cancellation mid-stream.

Common situations: Remote Dolt/MySQL connection reset during a large neighborhood read; context deadline exceeded on a big cascade; server-side query kill (max_execution_time).

Related errors


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