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]

Reply via email to