{"record":{"id":"5a4180b8b473f6d5","repo":"risingwavelabs/risingwave","slug":"inconsistent-operation-on-table-table-id-key","errorCode":null,"errorMessage":"Inconsistent operation on table {table_id} {key:?}, prev: {prev:?}, new: {new:?}","messagePattern":"Inconsistent operation on table (.+?) (.+?), prev: (.+?), new: (.+?)","errorType":"exception","errorClass":"MemTableError","httpStatus":null,"severity":"error","filePath":"src/storage/src/mem_table.rs","lineNumber":56,"sourceCode":"pub enum KeyOp {\n    Insert(Bytes),\n    Delete(Bytes),\n    /// (`old_value`, `new_value`)\n    Update((Bytes, Bytes)),\n}\n\n/// `MemTable` is a buffer for modify operations without encoding\n#[derive(Clone)]\npub struct MemTable {\n    table_id: TableId,\n    pub(crate) buffer: MemTableStore,\n    pub(crate) op_consistency_level: OpConsistencyLevel,\n    pub(crate) kv_size: KvSize,\n}\n\n#[derive(Error, Debug)]\npub enum MemTableError {\n    #[error(\"Inconsistent operation on table {table_id} {key:?}, prev: {prev:?}, new: {new:?}\")]\n    InconsistentOperation {\n        table_id: TableId,\n        key: TableKey<Bytes>,\n        prev: KeyOp,\n        new: KeyOp,\n    },\n}\n\ntype Result<T> = std::result::Result<T, Box<MemTableError>>;\n\npub type MemTableStore = BTreeMap<TableKey<Bytes>, KeyOp>;\npub struct MemTableIteratorBuilder;\npub struct MemTableRevIteratorBuilder;\n\nfn map_to_hummock_value<'a>(\n    (key, op): (&'a TableKey<Bytes>, &'a KeyOp),\n) -> (TableKey<&'a [u8]>, HummockValue<&'a [u8]>) {\n    (","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/storage/src/mem_table.rs#L38-L74","documentation":"A MemTable received a KeyOp that is inconsistent with the operation already recorded for the same key (e.g. inserting a key that was previously deleted, or conflicting delete/insert sequences). This enforces per-key operation consistency in the shared buffer memtable.","triggerScenarios":"Writing to a table where the same key already has a conflicting KeyOp (prev vs new), detected in MemTable::write under OpConsistencyLevel checks.","commonSituations":"Bugs in stream/batch write paths that replay or interleave operations incorrectly, upstream executor bugs re-writing tombstoned keys, or corrupted input data causing out-of-order operations.","solutions":["Inspect the reported prev and new KeyOp values to understand the conflict","Trace the writer producing the key ops (epoch, actor/task id) for a logic bug","Verify the upstream source or MV definition is not re-emitting conflicting ops for the same key","If triggered by malformed user data, validate/normalize input before writing"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match memtable.write(...).await {\n    Err(e) if matches!(e.as_ref(), MemTableError::InconsistentOperation { .. }) => {\n        tracing::error!(error = ?e, \"conflicting key op\");\n        // surface as data-corruption / trigger recovery\n    }\n    other => other?,\n}","preventionTips":["Ensure upstream operators emit at most one consistent op per key per epoch","Validate/replay input streams deterministically in tests","Track tombstones so deletes are respected before re-inserts"],"tags":["storage","memtable","consistency"],"backgroundTag":"invalid-state-transition","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}