gastownhall/beads · error
journal: read seq counter: %w
Error message
journal: read seq counter: %w
What it means
After advancing (or healing via the duplicate-key reactive path in insertEventRow), nextEventSeq reads the allocated value with SELECT next_seq FROM bd_events_seq WHERE id = 0. This error wraps that read failing. Unlike journal_prune.go's version, ErrNoRows here is NOT tolerated — the seq row must exist because advance() either incremented it or created/healed it.
Source
Thrown at internal/storage/issueops/journal.go:539
return res.RowsAffected()
}
n, err := advance()
if err != nil {
return 0, err
}
if n == 0 {
// The counter row is missing entirely: seed it at the journal's
// high-water mark, so the re-seed can never collide with an existing seq.
if err := healEventSeqCounter(ctx, tx); err != nil {
return 0, err
}
if _, err := advance(); err != nil {
return 0, err
}
}
var seq int64
if err := tx.QueryRowContext(ctx, "SELECT next_seq FROM bd_events_seq WHERE id = 0").Scan(&seq); err != nil {
return 0, fmt.Errorf("journal: read seq counter: %w", err)
}
return seq, nil
}
// compile-time assurance that *sql.Tx satisfies DBTX (the emit helpers accept
// both *sql.Tx and *sql.DB via DBTX).
var _ DBTX = (*sql.Tx)(nil)
View on GitHub (pinned to 71377f2769)
Solutions
- Verify the sentinel row exists: SELECT next_seq FROM bd_events_seq WHERE id = 0; re-insert it (INSERT INTO bd_events_seq (id, next_seq) VALUES (0, 1)) if missing.
- Re-run the schema migration to recreate bd_events_seq and its seed row.
- Retry the operation if the wrapped error is transient (connection/lock).
- Check for concurrent maintenance jobs that might truncate or rewrite bd_events_seq.
Example fix
// before DELETE FROM bd_events_seq; -- breaks next allocation // after UPDATE bd_events_seq SET next_seq = 1 WHERE id = 0; -- reset without removing the sentinel row
Defensive patterns
Strategy: validation
Validate before calling
var seq int64
err := db.QueryRow("SELECT next_seq FROM bd_events_seq WHERE id = 0").Scan(&seq)
if errors.Is(err, sql.ErrNoRows) {
_, _ = db.Exec("INSERT INTO bd_events_seq (id, next_seq) VALUES (0, 1)")
} Try / catch
if err != nil && strings.Contains(err.Error(), "journal: read seq counter") {
return fmt.Errorf("journal seq row missing or unreadable; re-run migrations: %w", err)
} Prevention
- Never manually DELETE from or drop bd_events_seq.
- Verify the id=0 sentinel row after restores/imports.
- Run migrations as a startup step.
- Avoid external jobs that truncate journal bookkeeping tables.
When it happens
Trigger: insertEventRow calling nextEventSeq when the SELECT on bd_events_seq returns a driver error (connection lost, table missing) — or returns ErrNoRows, which happens only if the row with id=0 vanished or the healing insert path silently failed to create it.
Common situations: Schema drift: bd_events_seq dropped or the id=0 row deleted manually; migration partially applied; transaction rolled back upstream so the healed row is invisible.
Related errors
- journal: advance seq counter: %w
- journal: read seq counter: %w
- journal: read since %d: %w
- set repo mtime: %w
- clear repo mtime: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1c7f1ae310b25d3d.
Report an issue: GitHub.