Skip to content

[Bug] Recovery seeds sequenceNr only from snapshot/events — a fully compacted journal permanently blocks persist #628

Description

@pathosDev

Problem

Replay.replayState seeds sequenceNr = 0 and only advances it from a replayed snapshot or replayed events — it never consults journal.highestSeq (src/persistence/Replay.ts:72, 93-99). PersistentActor adopts that value as _seq (src/persistence/PersistentActor.ts:231-232) and persistAll passes it as expectedSeq.

After a compaction that removed every event with no surviving snapshot, every backend correctly preserves its high-water mark (RelationalJournal.readHead, InMemoryJournal.highWater, Cassandra max_sequence_nr, DynamoDB deletedTo) — so the very next persist() throws JournalConcurrencyError(expected 0, actual N). Permanently. The actor can never write again.

This is the direct consequence of the fix for #379 (the high-water mark deliberately never rewinds); the replay seed was not updated to match. The journal contract suite has "full delete preserves highestSeq" (tests/integration/brokers/lib/persistence-contract/journal.ts:204), but nothing exercises the actor-level recovery path.

Proposed behaviour

Seed sequenceNr from max(snapshot.sequenceNr, await journal.highestSeq(persistenceId)) in replayState. assertTrustworthySnapshot already reads highestSeq, so the snapshot path pays no extra round-trip.

Acceptance criteria

  • Append 10 events, journal.delete(pid, 10), restart the actor → persisting event 11 succeeds.
  • Covered at the actor level (not only the journal contract), across the contract harnesses.

Related: #379 (closed — created this condition), companion issue on the deleteHistory footgun that triggers it: #629

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: highTop priority — high impact, plan nextproduction-goalBlocks or defines the path to production readiness

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions