risingwavelabs/risingwave · warning

should not read changelog from MockWaitEpochStateStore

Error message

should not read changelog from MockWaitEpochStateStore

What it means

This is a deliberate `panic!` in the `MockWaitEpochStateStore` test double's `StateStoreChangeEventLog::iter_log` implementation. The mock exists only to wait for epoch releases (DML backpressure testing) and must never serve real reads; any call to iter_log signals the test or executor used the mock in an unsupported way. It is an internal invariant guard, not a runtime error users should see in production.

Solutions

  1. Do not exercise changelog reads in tests that use MockWaitEpochStateStore; restrict it to the wait-epoch/DML backpressure scenario.
  2. Use a real or recording state store implementation (e.g. MemoryStateStore) when the test must call iter_log.
  3. If the panic appears unexpectedly, trace which executor path reads the changelog and gate that path off in the test setup.

Example fix

// before
let store = Arc::new(MockWaitEpochStateStore::new(...));
// executor under test reads changelog -> panics
// after: use a store that supports changelog reads
let store = MemoryStateStore::new();
Defensive patterns

Strategy: validation

Validate before calling

// assert the mock is only used where changelog reads never happen
assert!(
    !test_exercises_changelog_reads,
    "MockWaitEpochStateStore cannot serve iter_log; use MemoryStateStore"
);

Prevention

When it happens

Trigger: Any code path invoking `iter_log` on a `MockWaitEpochStateStore`, i.e. requesting a changelog iteration from the mock during a DML executor test.

Common situations: Writing or modifying a stream DML executor test that accidentally routes change-log reads through the mock; switching a test's state store from a real Hummock store to MockWaitEpochStateStore while the executor still exercises changelog reads.

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/deef98aeadeb05a3. Report an issue: GitHub.

Appendix: source

Thrown at src/stream/src/executor/dml.rs:486

    struct MockWaitEpochStateStore {
        wait_epoch_called_tx: Arc<Mutex<Option<WaitEpochCallSender>>>,
        wait_epoch_release_rx: Arc<tokio::sync::Mutex<Option<oneshot::Receiver<()>>>>,
    }

    impl StateStoreReadLog for MockWaitEpochStateStore {
        type ChangeLogIter = PanicStateStoreIter<StateStoreReadLogItem>;

        async fn next_epoch(&self, _epoch: u64, _options: NextEpochOptions) -> StorageResult<u64> {
            panic!("should not read changelog from MockWaitEpochStateStore")
        }

        async fn iter_log(
            &self,
            _epoch_range: (u64, u64),
            _key_range: TableKeyRange,
            _options: ReadLogOptions,
        ) -> StorageResult<Self::ChangeLogIter> {
            panic!("should not read changelog from MockWaitEpochStateStore")
        }
    }

    impl StateStore for MockWaitEpochStateStore {
        type Local = PanicStateStore;
        type ReadSnapshot = PanicStateStore;
        type VectorWriter = PanicStateStore;

        async fn try_wait_epoch(
            &self,
            epoch: HummockReadEpoch,
            options: TryWaitEpochOptions,
        ) -> StorageResult<()> {
            if let Some(tx) = self.wait_epoch_called_tx.lock().unwrap().take() {
                assert!(tx.send((epoch, options)).is_ok());
            }
            let rx = self.wait_epoch_release_rx.lock().await.take().unwrap();
            rx.await.unwrap();

View on GitHub (pinned to 6469eb736d)