gastownhall/beads · error

failed to check rows affected after seeding for prefix %q: %

Error message

failed to check rows affected after seeding for prefix %q: %w

What it means

This wraps a failure of res.RowsAffected() on the post-seeding retry UPDATE, mirroring error 2571 but on the second execution path. The driver failed to report how many rows the retried increment touched, so nextCounterIDTx cannot decide whether to insert an initial row. The code needs this value to distinguish 'counter row exists' from 'no numeric IDs found during seeding'.

Source

Thrown at internal/storage/dolt/issues.go:882

	rowsAffected, err := res.RowsAffected()
	if err != nil {
		return "", fmt.Errorf("failed to check rows affected for issue counter prefix %q: %w", prefix, err)
	}

	if rowsAffected == 0 {
		// No counter row yet - seed from existing issues before proceeding to
		// avoid collisions with manually-created sequential IDs (GH#2002).
		if seedErr := seedCounterFromExistingIssuesTx(ctx, tx, prefix); seedErr != nil {
			return "", fmt.Errorf("failed to seed issue counter for prefix %q: %w", prefix, seedErr)
		}
		// Retry the atomic increment after seeding.
		res, err = tx.ExecContext(ctx, "UPDATE issue_counter SET last_id = last_id + 1 WHERE prefix = ?", prefix)
		if err != nil {
			return "", fmt.Errorf("failed to increment issue counter after seeding for prefix %q: %w", prefix, err)
		}
		rowsAffected, err = res.RowsAffected()
		if err != nil {
			return "", fmt.Errorf("failed to check rows affected after seeding for prefix %q: %w", prefix, err)
		}
		if rowsAffected == 0 {
			// Seeding found no existing numeric IDs -- insert the initial row.
			_, err = tx.ExecContext(ctx, "INSERT INTO issue_counter (prefix, last_id) VALUES (?, 1)", prefix)
			if err != nil {
				return "", fmt.Errorf("failed to insert initial issue counter for prefix %q: %w", prefix, err)
			}
		}
	}

	// Read back the value that was atomically set by the DB engine.
	var nextID int
	err = tx.QueryRowContext(ctx, "SELECT last_id FROM issue_counter WHERE prefix = ?", prefix).Scan(&nextID)
	if err != nil {
		return "", fmt.Errorf("failed to read issue counter after increment for prefix %q: %w", prefix, err)
	}
	return fmt.Sprintf("%s-%d", prefix, nextID), nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped cause and upgrade/repair the Dolt driver to a version with reliable RowsAffected support.
  2. Test connectivity to the Dolt server; restart it if the connection state is suspect.
  3. Replace the driver if a custom/proxy driver strips affected-row metadata.
  4. Upgrade beads so the counter path tolerates missing rows-affected info via a read-back fallback.

Example fix

// before
rowsAffected, err = res.RowsAffected()
if err != nil {
    return "", fmt.Errorf("failed to check rows affected after seeding for prefix %q: %w", prefix, err)
}
// after
rowsAffected, err = res.RowsAffected()
if err != nil {
    var cur int
    switch scanErr := tx.QueryRowContext(ctx, "SELECT last_id FROM issue_counter WHERE prefix = ?", prefix).Scan(&cur); {
    case scanErr == nil:
        rowsAffected = 1
    case scanErr == sql.ErrNoRows:
        rowsAffected = 0
    default:
        return "", fmt.Errorf("failed to check rows affected after seeding for prefix %q: %w", prefix, err)
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

func isRowsAffectedErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "rows affected")
}

Try / catch

id, err := store.CreateIssue(ctx, issue)
if err != nil && strings.Contains(err.Error(), "check rows affected after seeding") {
    log.Printf("driver RowsAffected unsupported on post-seed path: %v", err)
    // upgrade driver/beads; transient failures may succeed on retry
}

Prevention

When it happens

Trigger: Counter-mode ID generation where the first UPDATE missed (no row), seeding ran, the retry UPDATE executed, but the driver's RowsAffected() call errored — driver protocol issue, connection degraded between exec and metadata read, or unsupported statement metadata.

Common situations: Mismatched Dolt driver/server versions; remote Dolt over an unstable connection; custom storage driver that doesn't implement RowsAffected correctly.

Related errors


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