risingwavelabs/risingwave · error

should not call rewind on it

Error message

should not call rewind on it

What it means

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.

Source

Thrown at src/stream/src/common/log_store_impl/in_mem.rs:269

        if let AwaitingTruncate {
            sealed_epoch,
            next_epoch,
        } = &self.epoch_progress
            && let TruncateOffset::Barrier { epoch } = offset
            && epoch == *sealed_epoch
        {
            let sealed_epoch = *sealed_epoch;
            self.epoch_progress = Consuming(*next_epoch);
            self.truncated_epoch_tx
                .send(sealed_epoch)
                .map_err(|_| anyhow!("unable to send sealed epoch"))?;
        }
        self.truncate_offset = offset;
        Ok(())
    }

    async fn rewind(&mut self) -> LogStoreResult<()> {
        Err(anyhow!("should not call rewind on it"))
    }

    async fn start_from(&mut self, _start_offset: Option<u64>) -> LogStoreResult<()> {
        Ok(())
    }
}

impl LogWriter for BoundedInMemLogStoreWriter {
    async fn init(
        &mut self,
        epoch: EpochPair,
        _pause_read_on_bootstrap: bool,
    ) -> LogStoreResult<()> {
        let init_epoch_tx = self.init_epoch_tx.take().expect("cannot be init for twice");
        self.wait_init_epoch
            .take()
            .expect("cannot be init for in-mem log store")(epoch)
        .await?;

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Do not call rewind on the in-memory log store; use truncate/start_from instead
  2. Add capability checks or specialize recovery paths per log store implementation
  3. Switch to a log store implementation that supports rewind if rewind semantics are required

Example fix

// before
log_store.rewind().await?;
// after
if log_store.supports_rewind() {
    log_store.rewind().await?;
}
Defensive patterns

Strategy: type-guard

Validate before calling

enum LogStoreCap { Rewind, NoRewind }
fn can_rewind(kind: LogStoreCap) -> bool { matches!(kind, LogStoreCap::Rewind) }

Type guard

fn supports_rewind(store: &dyn LogStore) -> bool {
    store.as_any().downcast_ref::<InMemLogStore>().is_none()
}

Prevention

When it happens

Trigger: Invoking LogStore::rewind on the in-memory log store implementation.

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/7893677a4afb22e7. Report an issue: GitHub.