gastownhall/beads · error

check issue existence in %s: rows: %w

Error message

check issue existence in %s: rows: %w

What it means

PresentIssueOrWispIDsInTx collects the IDs that actually exist in the issues/wisps tables by scanning result rows. After iterating rows it calls rows.Err() and wraps any driver-level iteration failure (network drop, context cancellation, driver decode error mid-stream) with this message. It means the existence check did not complete, so the returned set may be incomplete and must not be trusted.

Source

Thrown at internal/storage/issueops/edges.go:170

			rows, err := tx.QueryContext(ctx, fmt.Sprintf(
				"SELECT id FROM %s WHERE id IN (%s)", table, strings.Join(placeholders, ",")), args...)
			if err != nil {
				if isTableNotExistError(err) {
					break
				}
				return nil, fmt.Errorf("check issue existence in %s: %w", table, err)
			}
			for rows.Next() {
				var id string
				if scanErr := rows.Scan(&id); scanErr != nil {
					_ = rows.Close()
					return nil, fmt.Errorf("check issue existence in %s: scan: %w", table, scanErr)
				}
				present[id] = struct{}{}
			}
			_ = rows.Close()
			if err := rows.Err(); err != nil {
				return nil, fmt.Errorf("check issue existence in %s: rows: %w", table, err)
			}
		}
	}
	return present, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the edge operation; the error is transient if caused by connection/context interruption.
  2. Check the wrapped cause (%w) for context.Canceled / context.DeadlineExceeded and increase the timeout or fix the caller that cancelled.
  3. Verify the database connection is healthy (bd doctor / ping) if it recurs.
  4. Check Dolt server logs for connection resets if using a remote database.

Example fix

// before
present, err := PresentIssueOrWispIDsInTx(ctx, tx, ids)
if err != nil { return err }
// after
present, err := PresentIssueOrWispIDsInTx(ctx, tx, ids)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        ctx = context.Background() // or raise the deadline
        present, err = PresentIssueOrWispIDsInTx(ctx, tx, ids)
    }
    if err != nil { return err }
}
Defensive patterns

Strategy: retry

Validate before calling

if err := db.PingContext(ctx); err != nil { return fmt.Errorf("db unavailable: %w", err) }
if ctx.Err() != nil { return ctx.Err() }

Type guard

func isRowsIterationErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "check issue existence") && strings.Contains(err.Error(), ": rows: ")
}

Try / catch

present, err := PresentIssueOrWispIDsInTx(ctx, tx, ids)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        return retryWithFreshCtx(ctx)
    }
    return fmt.Errorf("edge existence check failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ExecuteEdgeCount or ExecuteEdgeRead when the underlying `SELECT id FROM ... WHERE id IN (...)` row stream fails after the query itself succeeded — e.g. the Dolt/MySQL connection breaks or the context is cancelled while rows are being iterated.

Common situations: Long-running edge operations interrupted by an idle-connection timeout on the database; a request context cancelled by an HTTP client disconnect; flaky network between bd and a remote Dolt server.

Related errors


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