cube-js/cube · error

{:?}

Error message

{:?}

What it means

CubeStore's try_encode serializes a DataFusion logical/physical plan node into an ExtensionNodeSerialized variant; when it encounters a node type not covered by the downcast match (e.g. an unhandled ClusterAggregate* or other Extension node), it reaches todo!("{:?}", node) and panics, printing the offending node. This means the planner produced a plan the serialization layer does not know how to encode for distribution.

Source

Thrown at rust/cubestore/cubestore/src/queryplanner/serialized_plan.rs:1307

            node.node.as_any().downcast_ref::<RollingWindowAggregate>()
        {
            ExtensionNodeSerialized::RollingWindowAggregate(
                rolling_window_aggregate.to_serialized()?,
            )
        } else if let Some(topk_aggregate) = node
            .node
            .as_any()
            .downcast_ref::<ClusterAggregateTopKUpper>()
        {
            ExtensionNodeSerialized::ClusterAggregateTopKUpper(topk_aggregate.to_serialized()?)
        } else if let Some(topk_aggregate) = node
            .node
            .as_any()
            .downcast_ref::<ClusterAggregateTopKLower>()
        {
            ExtensionNodeSerialized::ClusterAggregateTopKLower(topk_aggregate.to_serialized()?)
        } else {
            todo!("{:?}", node)
        };
        to_serialize
            .serialize(&mut ser)
            .map_err(|e| DataFusionError::Execution(format!("try_encode: {}", e)))?;
        buf.extend(ser.take_buffer());
        Ok(())
    }

    fn try_decode_table_provider(
        &self,
        buf: &[u8],
        _table_ref: &TableReference,
        _schema: SchemaRef,
        _ctx: &SessionContext,
    ) -> datafusion::common::Result<Arc<dyn TableProvider>> {
        use serde::Deserialize;
        let r = flexbuffers::Reader::get_root(buf)
            .map_err(|e| DataFusionError::Execution(format!("try_decode_table_provider: {}", e)))?;

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Upgrade all CubeStore/cubesql components to matching versions so plan node sets align
  2. Inspect the panicking node printed by the panic and add a serialization arm for it in rust/cubestore/cubestore/src/queryplanner/serialized_plan.rs try_encode
  3. Rewrite the query to avoid the unsupported construct (e.g. simplify ORDER BY/LIMIT aggregates so the TopK extension path is not taken)

Example fix

// before
} else {
    todo!("{:?}", node)
};
// after
} else if let Some(topk) = node.as_any().downcast_ref::<ClusterAggregateTopKUpper>() {
    ExtensionNodeSerialized::ClusterAggregateTopKUpper(topk.to_serialized()?)
} else {
    return Err(DataFusionError::Internal(format!(
        "try_encode: unsupported plan node {:?}", node
    )));
};
Defensive patterns

Strategy: retry

Validate before calling

// Ensure planner components are version-aligned before running distributed queries
if (cubesqlVersion.major !== cubestoreVersion.major || cubesqlVersion.minor !== cubestoreVersion.minor) {
  throw new Error('cubesql/cubestore version mismatch: upgrade all nodes together to avoid unsupported plan node serialization');
}

Type guard

// Server-side guard before reaching the todo!
fn can_encode(node: &Arc<dyn PhysicalPlan>) -> bool {
    node.as_any().downcast_ref::<ClusterAggregateTopKLower>().is_some()
        || node.as_any().downcast_ref::<ClusterAggregateTopKUpper>().is_some() // ...list all supported nodes
}

Try / catch

// Client: catch the distributed-query failure and fall back to a simpler query
let result = match cluster.query(&sql).await {
    Ok(r) => r,
    Err(e) if e.to_string().contains("not implemented") || e.to_string().contains("panic") => {
        cluster.query(&simplify_query(&sql)).await? // e.g. drop exotic ORDER BY/LIMIT aggregates
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Executing a distributed CubeStore query whose plan contains an extension node missing from the try_encode match (e.g. a new/unsupported ClusterAggregateTopK variant, TopK besides Lower, or another extension node added without updating serialization).

Common situations: Version skew between cubestore nodes or between cubesql and cubestore where one side emits a plan node the other can't serialize; newly added planner features used before serialization support landed; queries hitting TopK/aggregate fast paths with unusual orderings/limits.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/27653e766c21e47c. Report an issue: GitHub.