eudaimos opened a new issue, #40732:
URL: https://github.com/apache/superset/issues/40732
### Bug description
The `superset.mcp_service` `generate_chart` and `update_chart` tools fail to
compile a query when building a `table` chart in **raw mode** (no aggregate
functions on any column) against a **physical dataset**. The tool accepts the
column list into `form_data.all_columns`, but no `query_context` is produced
and the request fails with the misleading `Empty query?` compile error.
This is a different code path from #40570 — there is no Jinja templating
involved, and the dataset is physical, not virtual. Surface error string is the
same.
### Environment
- Apache Superset image:
`apachesuperset.docker.scarf.sh/apache/superset:6.1.0rc1`
- MCP server: `superset.mcp_service` running via `fastmcp` `streamable-http`
transport (in-process with the Flask app), started from the same image as a
sidecar container.
- ClickHouse backend; database object is a ClickHouse `VIEW` registered as a
Superset physical dataset.
### How to reproduce
1. Create a physical dataset against any database table or view that returns
one or more fully-populated rows (no Jinja, no template params). Example: a
ClickHouse view exposing a "latest snapshot" of KPI metrics via `argMax(col,
snapshot_at)`.
2. Call the MCP `generate_chart` tool with a raw-mode table config (no
`aggregate` on any column):
```json
{
"dataset_id": <id>,
"save_chart": false,
"config": {
"chart_type": "table",
"viz_type": "table",
"columns": [
{"name": "total_active_brands"},
{"name": "brands_with_yt_connected"},
{"name": "pct_brands_with_yt"}
]
}
}
```
3. Observe the response:
```json
{
"success": false,
"form_data": {
"viz_type": "table",
"all_columns":
["total_active_brands","brands_with_yt_connected","pct_brands_with_yt"],
"query_mode": "raw",
"include_time": false,
"order_desc": true,
"row_limit": 1000
},
"error": {
"error_type": "compile_error",
"message": "Chart query failed to execute. The chart configuration is
invalid.",
"details": "Error: Empty query?",
"error_code": "CHART_COMPILE_FAILED"
}
}
```
Note that `form_data.all_columns` is populated correctly — the tool
understood the column names — but the query never compiles.
4. The same failure mode also occurs via `update_chart`: targeting an
existing, working chart with a raw-mode table config writes the configuration
but produces no usable `query_context`. Subsequent reads via `get_chart_data`
then fail with:
```json
{
"error": "Chart <id> (type: table) has no saved query_context and its
form_data does not contain recognizable metrics or columns. Please open this
chart in Superset and re-save it to generate a query_context.",
"error_type": "MissingQueryContext"
}
```
…confirming that the MCP path doesn't produce the same `query_context`
that the Explore UI would when saving the equivalent chart.
### Expected behavior
A raw-mode table chart against a physical dataset should compile and render.
The Explore UI lets users build exactly this shape of chart with no aggregates
by switching Query mode → "Raw records" and dragging columns into the Columns
slot. The MCP `generate_chart`/`update_chart` tools should support the same
shape.
### Actual behavior
`all_columns` is captured into `form_data` but no `query_context` is
generated, so the chart-preview / data-load pipeline sees no metrics, no
group-bys, and no raw columns it recognizes — producing the `Empty query?`
compile error on save, and `MissingQueryContext` on read for charts updated
this way.
### Workaround
Add a no-op aggregate to each column to push the chart down the
aggregate-mode code path. For a dataset that always returns a single row (e.g.
a `latest-snapshot` view), `MAX` is semantically a no-op and produces the right
values:
```json
{
"columns": [
{"name": "total_active_brands", "aggregate": "MAX", "label": "Total
Active Brands"},
{"name": "brands_with_yt_connected", "aggregate": "MAX", "label":
"Brands with YT Connected"},
{"name": "pct_brands_with_yt", "aggregate": "MAX", "label": "% Brands
with YT"}
]
}
```
With the `MAX` workaround the chart saves, renders, and `get_chart_data`
returns the expected single-row result. Custom `label` keeps the column header
clean.
This is a workaround, not a fix — the saved chart definition lies about what
it's doing (`MAX` of a 1-row aggregate is misleading to anyone reading the
chart's saved config later).
### Impact
Any team trying to build "scorecard"-style table charts via MCP — where each
column is a precomputed value from the dataset and no aggregation is intended —
has to either:
- Add cosmetic `MAX`/`SUM`/etc. aggregates to every column, or
- Build the chart in the Superset UI and skip MCP for that flow.
For our use case (a hourly-refreshed gold-layer view that already aggregates
upstream into a single row of KPIs), there is no semantic aggregation that the
chart should be performing — the dataset is already the answer.
### Possibly relevant
Same surface error as #40570 (Jinja-in-virtual-datasets), but completely
different cause: this one is in the raw-mode table chart compile path, not in
template materialization. Worth cross-referencing in case maintainers touching
the same chart-preview compile pipeline want to fix both at once.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]