clockworklabs/SpacetimeDB · error

`CommittedState::replay_table_updated` should be empty at th

Error message

`CommittedState::replay_table_updated` should be empty at the end of a commit, but found {} entries

What it means

replay_end_tx requires replay_table_updated to be drained by the end of each committed transaction: entries are added when a new st_table row is seen during replay and removed when the corresponding old st_table row is deleted (visit_delete for ST_TABLE_ID). Non-empty means a table schema update ended without its predecessor being cleaned up, so replay fails rather than continue with ambiguous state.

Source

Thrown at crates/datastore/src/locking_tx_datastore/replay.rs:1063

        // as if that happens, the database is bricked.

        table.clear(blob_store);

        Ok(())
    }

    fn replay_end_tx(&mut self) -> Result<()> {
        self.next_tx_offset += 1;

        if !self.replay_columns_to_ignore.is_empty() {
            return Err(anyhow::anyhow!(
                "`CommittedState::replay_columns_to_ignore` should be empty at the end of a commit, but found {} entries",
                self.replay_columns_to_ignore.len(),
            ).into());
        }

        if !self.replay_table_updated.is_empty() {
            return Err(anyhow::anyhow!(
                "`CommittedState::replay_table_updated` should be empty at the end of a commit, but found {} entries",
                self.replay_table_updated.len(),
            )
            .into());
        }

        // Any dropped tables should be fully gone by the end of a transaction;
        // if we see any reference to them in the future we should error, not ignore.
        self.replay_table_dropped.clear();

        Ok(())
    }
}

pub(super) fn build_sequence_state(datastore: &Locking, cs: &mut CommittedState) -> Result<()> {
    let sequence_state = cs.build_sequence_state()?;
    // Reset our sequence state so that they start in the right places.
    *datastore.sequence_state.lock() = sequence_state;

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Restore from a snapshot taken before the affected transaction
  2. Replay with the spacetimedb version that wrote the schema change
  3. Report the invariant violation with the commitlog for diagnosis
Defensive patterns

Strategy: fallback

Try / catch

Catch at open, restore from a snapshot taken before the affected transaction, and report the invariant violation with the commitlog for root-causing.

Prevention

When it happens

Trigger: A schema-change transaction whose st_table delete row is missing from the log (corruption or truncation); reordered system-table writes from a different version; a bug in the add/remove pairing during replay of renames or column additions.

Common situations: Crash mid table-rename or column-add commit; version skew between writer and replayer; fuzzed commitlogs.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/caddbbae58725ae8. Report an issue: GitHub.