{"record":{"id":"7893677a4afb22e7","repo":"risingwavelabs/risingwave","slug":"should-not-call-rewind-on-it","errorCode":null,"errorMessage":"should not call rewind on it","messagePattern":"should not call rewind on it","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/common/log_store_impl/in_mem.rs","lineNumber":269,"sourceCode":"        if let AwaitingTruncate {\n            sealed_epoch,\n            next_epoch,\n        } = &self.epoch_progress\n            && let TruncateOffset::Barrier { epoch } = offset\n            && epoch == *sealed_epoch\n        {\n            let sealed_epoch = *sealed_epoch;\n            self.epoch_progress = Consuming(*next_epoch);\n            self.truncated_epoch_tx\n                .send(sealed_epoch)\n                .map_err(|_| anyhow!(\"unable to send sealed epoch\"))?;\n        }\n        self.truncate_offset = offset;\n        Ok(())\n    }\n\n    async fn rewind(&mut self) -> LogStoreResult<()> {\n        Err(anyhow!(\"should not call rewind on it\"))\n    }\n\n    async fn start_from(&mut self, _start_offset: Option<u64>) -> LogStoreResult<()> {\n        Ok(())\n    }\n}\n\nimpl LogWriter for BoundedInMemLogStoreWriter {\n    async fn init(\n        &mut self,\n        epoch: EpochPair,\n        _pause_read_on_bootstrap: bool,\n    ) -> LogStoreResult<()> {\n        let init_epoch_tx = self.init_epoch_tx.take().expect(\"cannot be init for twice\");\n        self.wait_init_epoch\n            .take()\n            .expect(\"cannot be init for in-mem log store\")(epoch)\n        .await?;","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/common/log_store_impl/in_mem.rs#L251-L287","documentation":"Guard in the in-memory log store's rewind: rewind is not supported by this log store implementation (it only supports forward truncation). Any call to rewind on the in-memory log store is a programming error and fails with this message.","triggerScenarios":"Invoking LogStore::rewind on the in-memory log store implementation.","commonSituations":"Generic log-store handling code that calls rewind without checking implementation capabilities, or recovery logic written for a different (e.g. file/Redis-based) log store.","solutions":["Do not call rewind on the in-memory log store; use truncate/start_from instead","Add capability checks or specialize recovery paths per log store implementation","Switch to a log store implementation that supports rewind if rewind semantics are required"],"exampleFix":"// before\nlog_store.rewind().await?;\n// after\nif log_store.supports_rewind() {\n    log_store.rewind().await?;\n}","handlingStrategy":"type-guard","validationCode":"enum LogStoreCap { Rewind, NoRewind }\nfn can_rewind(kind: LogStoreCap) -> bool { matches!(kind, LogStoreCap::Rewind) }","typeGuard":"fn supports_rewind(store: &dyn LogStore) -> bool {\n    store.as_any().downcast_ref::<InMemLogStore>().is_none()\n}","tryCatchPattern":null,"preventionTips":["Branch recovery logic on log store implementation capabilities","Never call rewind on in-memory log stores","Encode capabilities in the log store trait (e.g. fn supports_rewind(&self) -> bool)"],"tags":["stream","log-store","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}