{"record":{"id":"5d25060c50a70e7a","repo":"clockworklabs/SpacetimeDB","slug":"delete-without-active-mutable-transaction","errorCode":null,"errorMessage":"delete without active mutable transaction","messagePattern":"delete without active mutable transaction","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/dst/src/engine.rs","lineNumber":236,"sourceCode":"                    Ok((_generated_columns, row, _flags)) => InsertOutcome::Accepted(row.to_product_value()),\n                    // Generated rows can intentionally hit unique constraints; the oracle validates that rejection.\n                    Err(error) if Self::is_unique_constraint_violation(&error) => {\n                        InsertOutcome::UniqueConstraintViolation\n                    }\n                    Err(error) => return Err(error.into()),\n                };\n                Ok(Observation::Inserted { outcome })\n            }\n            Interaction::Delete { table, row } => {\n                let table_id = self.table_ids[*table];\n                let db = self\n                    .db\n                    .as_ref()\n                    .ok_or_else(|| anyhow::anyhow!(\"database is not open\"))?;\n                let tx = self\n                    .active_mut_tx\n                    .as_mut()\n                    .ok_or_else(|| anyhow::anyhow!(\"delete without active mutable transaction\"))?;\n                db.delete_by_rel(tx, table_id, [row.clone()]);\n                Ok(Observation::Deleted)\n            }\n            Interaction::CommitTx => {\n                let tx = self\n                    .active_mut_tx\n                    .take()\n                    .ok_or_else(|| anyhow::anyhow!(\"commit without active mutable transaction\"))?;\n                let db = self\n                    .db\n                    .as_ref()\n                    .ok_or_else(|| anyhow::anyhow!(\"database is not open\"))?;\n                let Some((_tx_offset, tx_data, _tx_metrics, _reducer)) = db.commit_tx(tx)? else {\n                    anyhow::bail!(\"commit produced no transaction data\");\n                };\n                Ok(Observation::Committed {\n                    delta: self.commit_delta_from_tx_data(&tx_data),\n                })","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/dst/src/engine.rs#L218-L254","documentation":"Delete interactions in the dst engine require an open mutable transaction: self.active_mut_tx was None because no BeginMutTx preceded the Delete, or the previous transaction already ended via CommitTx or was discarded by a Replay interaction.","triggerScenarios":"Sequence beginning with Delete; Delete after CommitTx without a new BeginMutTx; Delete after Replay (which implicitly takes and drops the active transaction).","commonSituations":"Workload-generator state-machine bugs; hand-written interaction lists in DST tests; misunderstandings of Replay's implicit transaction discard.","solutions":["Emit BeginMutTx before any Insert/Delete pair and CommitTx after","Track active-transaction state in the generator and forbid data ops outside a tx","After Replay, begin a new transaction before further data ops","Assert in the driver that Delete only follows a successful BeganMutTx"],"exampleFix":"// before: delete outside any transaction\nvec![Delete { .. }, CommitTx]\n\n// after: open, delete, commit\nvec![BeginMutTx, Delete { .. }, CommitTx]","handlingStrategy":"validation","validationCode":"// Sequence-level guard before emitting a Delete\nfn sequence_allows_delete(tx_active: bool) -> bool {\n    tx_active\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Emit BeginMutTx before any Delete and CommitTx afterwards","Remember that Replay discards the active transaction — re-begin before further deletes","Model tx lifecycle explicitly in generators instead of emitting ops independently"],"tags":["rust","spacetimedb","dst","testing","transaction","state-machine"],"backgroundTag":"no-active-transaction","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}