gastownhall/beads · error

row iteration error: %w

Error message

row iteration error: %w

What it means

After streaming result rows, OrphanedDependencies checks rows.Err() — the mandatory database/sql step that surfaces errors encountered during iteration (network drop mid-result-set, driver decode failure). If iteration failed, the collected orphan list may be incomplete, so the function refuses to continue and wraps the error as "row iteration error" to avoid deleting only a partial set.

Source

Thrown at cmd/bd/doctor/fix/validation.go:71

		return fmt.Errorf("failed to query orphaned dependencies: %w", err)
	}
	defer rows.Close()

	type orphan struct {
		depTable    string
		issueID     string
		dependsOnID string
	}
	var orphans []orphan

	for rows.Next() {
		var o orphan
		if err := rows.Scan(&o.depTable, &o.issueID, &o.dependsOnID); err == nil {
			orphans = append(orphans, o)
		}
	}
	if err := rows.Err(); err != nil {
		return fmt.Errorf("row iteration error: %w", err)
	}

	if len(orphans) == 0 {
		fmt.Println("  No orphaned dependencies to fix")
		return nil
	}

	// Delete orphaned dependencies
	// Uses explicit transaction so writes persist when @@autocommit is OFF
	// (e.g. Dolt server started with --no-auto-commit).
	showIndividual := verbose || len(orphans) < 20
	tx, err := db.Begin()
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %w", err)
	}
	var removed int
	for _, o := range orphans {
		var err error

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run the fix — this is usually transient; the SELECT restarts from scratch.
  2. Check Dolt server logs for a crash or connection kill around the time of the run; stabilize the server/connection.
  3. Increase connection/network timeouts if large result sets are being truncated by a proxy or idle timeout.
  4. Upgrade the Dolt driver/server if decode errors recur (version mismatch between client driver and server).

Example fix

// before: connection drops mid-iteration, partial orphans discarded safely
for rows.Next() {
	if err := rows.Scan(&o.depTable, &o.issueID, &o.dependsOnID); err == nil {
		orphans = append(orphans, o)
	}
}
if err := rows.Err(); err != nil {
	return fmt.Errorf("row iteration error: %w", err)
}
// after: retry the whole function on a healthy connection
// (fix has no partial side effects at this stage — the DELETE transaction has not started)
Defensive patterns

Strategy: retry

Validate before calling

// probe connectivity before a long-running fix
if err := db.PingContext(ctx); err != nil {
	return fmt.Errorf("database unreachable, aborting fix: %w", err)
}

Type guard

var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
	// transient network failure during row iteration — safe to retry
}

Try / catch

err := fix.OrphanedDependencies(path, verbose)
if err != nil && strings.Contains(err.Error(), "row iteration error") {
	// no writes have happened yet; safe to retry once
	err = fix.OrphanedDependencies(path, verbose)
}
if err != nil {
	log.Fatalf("orphan fix failed: %v", err)
}

Prevention

When it happens

Trigger: rows.Next()/rows.Scan sequence hits a driver-level error while fetching the result set: connection terminated mid-query on a remote Dolt server, packet corruption/timeout, or a driver decode error on a column value.

Common situations: Large result set over a flaky connection to a networked Dolt server; server killed or OOM during the SELECT; keep-alive/proxy timeout cutting the connection while rows stream; Dolt version mismatch producing unexpected column values.

Related errors


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