risingwavelabs/risingwave · error · StreamExecutorError

missing log_store_table in SyncLogStoreNode

Error message

missing log_store_table in SyncLogStoreNode

What it means

Constructing a `SyncLogStoreDispatcher` requires the proto's `log_store_table` field, but the `SyncLogStoreNode` message arrived without it. This is a required protobuf field that the meta node must set when planning the actor's dispatcher.

Solutions

  1. Ensure meta and frontend/stream binaries are the same version — complete any in-progress rolling upgrade.
  2. Inspect the actor plan sent by meta to confirm `log_store_table` is populated; if not, this is a meta-side plan generation bug — file an issue.
  3. Restart the actor/cluster after aligning versions so plans are regenerated.
Defensive patterns

Strategy: validation

Validate before calling

// before building the dispatcher
if sync.log_store_table.is_none() { return Err(anyhow!("SyncLogStoreNode.log_store_table missing; check meta/stream version alignment")); }

Type guard

fn has_log_store_table(n: &SyncLogStoreNode) -> bool { n.log_store_table.is_some() }

Try / catch

SyncLogStoreDispatcher::new(sync, &actor_context).await.map_err(|e| { error!("sync log store dispatcher init failed: {e}"); e })?;

Prevention

When it happens

Trigger: `new` is called with a `SyncLogStoreNode` whose `log_store_table` option is None — i.e. the fragment/dispatcher plan from meta omitted the log store table id, typically due to a version-skew between meta and stream binaries or a plan-serialization bug.

Common situations: Rolling upgrade where an older meta node produces plans for a newer stream binary that requires the field; corrupted/partial actor plan dispatch; internal bug in plan construction.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/stream/src/executor/dispatch/dispatch_sync_log_store.rs:80

        actor_context: &ActorContextRef,
        sync: &stream_plan::SyncLogStoreNode,
        vnode_bitmap: Option<Bitmap>,
        state_store: S,
    ) -> StreamResult<Self> {
        let chunk_size = actor_context.config.developer.chunk_size;
        let fragment_id = actor_context.fragment_id;
        let log_store_metrics = SyncedKvLogStoreMetrics::new(
            &actor_context.streaming_metrics,
            actor_context.id,
            fragment_id,
            "sync_log_store_dispatch",
            "sync_log_store_dispatch",
        );

        let table = sync
            .log_store_table
            .as_ref()
            .ok_or_else(|| anyhow!("missing log_store_table in SyncLogStoreNode"))?;

        let pause_duration_ms = actor_context
            .config
            .developer
            .sync_log_store_pause_duration_ms;
        let max_buffer_size = actor_context.config.developer.sync_log_store_buffer_size;

        let serde =
            LogStoreRowSerde::new(table, vnode_bitmap.map(Into::into), &KV_LOG_STORE_V2_INFO);
        let log_store_context = SyncKvLogStoreContext {
            table_id: table.id,
            fragment_id,
            serde,
            state_store,
            max_buffer_size,
            pause_duration_ms: Duration::from_millis(pause_duration_ms as _),
            aligned: sync.aligned,
            chunk_size,

View on GitHub (pinned to 6469eb736d)