This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch viz-pipeline-followups
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 833fca4e1fd781e0033c06dbe46bf8441723a777
Author: Claude Code <[email protected]>
AuthorDate: Tue Jul 28 01:23:07 2026 -0700

    fix(migrations): don't KeyError on a query_context missing "queries"
    
    upgrade_slice assumed a stored query_context always carries a
    "queries" key. An atypical one (e.g. hand-edited via the API) missing
    it raised a bare KeyError inside the broad except, after viz_type had
    already been flipped -- leaving the slice half-migrated (new
    viz_type, but stale params/query_context in the old shape).
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 superset/migrations/shared/migrate_viz/base.py     |  8 +++-
 .../viz/upgrade_malformed_query_context_test.py    | 46 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/superset/migrations/shared/migrate_viz/base.py 
b/superset/migrations/shared/migrate_viz/base.py
index 86e97a99490..8d99189f58d 100644
--- a/superset/migrations/shared/migrate_viz/base.py
+++ b/superset/migrations/shared/migrate_viz/base.py
@@ -167,7 +167,13 @@ class MigrateViz:
                 if "form_data" in query_context:
                     query_context["form_data"] = clz.data
 
-                queries_bak = copy.deepcopy(query_context["queries"])
+                # A stored query_context is expected to carry "queries", but
+                # an atypical/malformed one (e.g. hand-edited via the API)
+                # missing it must not raise here: viz_type was already
+                # flipped above, so an uncaught exception at this point
+                # would leave the slice half-migrated (new viz_type, but
+                # stale params/query_context in the old shape).
+                queries_bak = copy.deepcopy(query_context.get("queries"))
 
                 queries = clz._build_query()["queries"]
                 query_context["queries"] = queries
diff --git 
a/tests/unit_tests/migrations/viz/upgrade_malformed_query_context_test.py 
b/tests/unit_tests/migrations/viz/upgrade_malformed_query_context_test.py
new file mode 100644
index 00000000000..21e822c1a3f
--- /dev/null
+++ b/tests/unit_tests/migrations/viz/upgrade_malformed_query_context_test.py
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from superset.migrations.shared.migrate_viz import MigrateLineChart
+from superset.models.slice import Slice
+from superset.utils import json
+
+
+def test_upgrade_slice_survives_a_query_context_without_queries() -> None:
+    """A stored query_context is expected to carry "queries", but
+    upgrade_slice must not leave a slice half-migrated (new viz_type, stale
+    params/query_context) if an atypical one doesn't -- it used to raise a
+    bare KeyError there, caught by the broad except, after viz_type had
+    already been flipped."""
+    source = {"viz_type": "line", "datasource": "1__table", "x_axis_label": 
"x"}
+
+    slc = Slice(
+        viz_type="line",
+        datasource_type="table",
+        params=json.dumps(source),
+        # No "queries" key, unlike a normal query_context.
+        query_context=json.dumps({"form_data": source}),
+    )
+
+    MigrateLineChart.upgrade_slice(slc)
+
+    assert slc.viz_type == "echarts_timeseries_line"
+    upgraded_params = json.loads(slc.params)
+    assert upgraded_params["form_data_bak"] == source
+    assert upgraded_params.get("queries_bak") is None
+    assert json.loads(slc.query_context)["form_data"]["viz_type"] == (
+        "echarts_timeseries_line"
+    )

Reply via email to