cube-js/cube · error
Unsupported extension node: {}
Error message
Unsupported extension node: {} What it means
During LogicalPlan-to-Cube-plan conversion, LogicalPlan::Extension nodes (DataFusion's escape hatch for custom, user-defined plan nodes) have no mapping into Cube's plan language and trigger an explicit panic. The message includes the extension node's schema for diagnostics.
Source
Thrown at rust/cubesql/cubesql/src/compile/rewrite/converter.rs:821
self.graph
.add(LogicalPlanLanguage::Limit([skip, fetch, input]))
}
LogicalPlan::Values(values) => {
let values = add_data_node!(self, values.values, ValuesValues);
self.graph.add(LogicalPlanLanguage::Values([values]))
}
LogicalPlan::CreateExternalTable { .. } => {
panic!("CreateExternalTable is not supported");
}
LogicalPlan::Explain { .. } => {
panic!("Explain is not supported");
}
LogicalPlan::Analyze { .. } => {
panic!("Analyze is not supported");
}
// TODO
LogicalPlan::Extension(ext) => {
panic!("Unsupported extension node: {}", ext.node.schema());
}
LogicalPlan::Distinct(distinct) => {
let input = self.add_logical_plan_replace_params(
distinct.input.as_ref(),
query_params,
ctx,
)?;
self.graph.add(LogicalPlanLanguage::Distinct([input]))
}
// TODO: Support all
_ => unimplemented!("Unsupported node type: {:?}", plan),
})
}
fn find_source_table_name(&self, plan: &LogicalPlan) -> Result<Option<String>, CubeError> {
Ok(match plan {
LogicalPlan::Projection(node) => self.find_source_table_name(node.input.as_ref())?,
LogicalPlan::Filter(node) => self.find_source_table_name(node.input.as_ref())?,
LogicalPlan::Window(node) => self.find_source_table_name(node.input.as_ref())?,View on GitHub (pinned to 7d981676b3)
Solutions
- Identify the extension node name from the schema in the message and rewrite the query without it
- Upgrade CubeSQL — many extension nodes are later given real conversions
- Open/consult a Cube issue for the specific operator to add a LogicalPlanLanguage mapping
Defensive patterns
Strategy: try-catch
Try / catch
// catch_unwind around planner entry, since this is a panic not a Result
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| planner.plan(sql)));
match result {
Ok(plan) => plan,
Err(p) => { log::error!("plan conversion failed: {:?}", p); Err(planning_failed_response()) }
} Prevention
- Avoid DataFusion extension operators / UDF plan nodes in queries sent to CubeSQL
- Keep CubeSQL and Cube server versions aligned
- Read the extension schema name in the panic to identify the offending operator quickly
When it happens
Trigger: The plan being converted contains a custom/extension operator — e.g. a UDF node, a custom table function, or a DataFusion plugin node injected upstream of the converter.
Common situations: Using DataFusion extension points or third-party extensions with CubeSQL; a CubeSQL version where a newly added builtin operator is still represented as an Extension node; raw SQL that maps to an unsupported function.
Related errors
- Analyze is not supported
- This query doesnt have a plan, because it already has values
- Should be rewritten with UtcTimestamp function
- CreateExternalTable is not supported
- Explain is not supported
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/f8cd890cfba2c142.
Report an issue: GitHub.