Skip to content

fix(mcp): reject unsafe dashboard layout replacements - #43367

Closed
aminghadersohi wants to merge 3 commits into
apache:masterfrom
aminghadersohi:aminghadersohi/ch117987/validate-dashboard-layout-updates
Closed

fix(mcp): reject unsafe dashboard layout replacements#43367
aminghadersohi wants to merge 3 commits into
apache:masterfrom
aminghadersohi:aminghadersohi/ch117987/validate-dashboard-layout-updates

Conversation

@aminghadersohi

@aminghadersohi aminghadersohi commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Reject unsafe full position_json replacements in the MCP update_dashboard tool before they overwrite a valid saved layout.

Superset renders only layout nodes reachable from ROOT_ID, but dashboard hydration indexes every CHART node in position_json. An unreachable chart therefore prevents the normal missing-chart fallback while remaining invisible, which can leave a dashboard blank even though the chart nodes and slice associations still exist.

This change validates renderer-required component shape, the v2 marker, graph references, parent/child compatibility, cycles, component IDs, parent paths, reachability, and root/top-level-tab shape. Traversal is iterative, imported decimal-string chart IDs are normalized through a helper shared with chart removal, and DYNAMIC nodes are rejected because the backend cannot validate the frontend registry. Reachable chart IDs must exactly match the charts associated with the dashboard.

Invalid updates return InvalidDashboardLayout before any field mutation or commit, preserving the previous layout. The validator handles Superset's two reserved exceptions: detached HEADER_ID, and the empty detached GRID_ID retained by top-level tab layouts.

The MCP schema now explicitly states that get_dashboard_layout is a summary rather than a round-trippable raw tree, so callers are not directed into unsafe incremental full replacements.

Tracking: SC-117987 [sc-117987]

Related: #43133 contains generate-only fallback validation as part of native AI authoring. This PR provides the stronger shared validator for that path to reuse after rebase while keeping update rejection separate from generate fallback behavior.

TESTING INSTRUCTIONS

  • pre-commit run --files superset/mcp_service/dashboard/layout_validation.py superset/mcp_service/dashboard/schemas.py superset/mcp_service/dashboard/tool/update_dashboard.py superset/mcp_service/dashboard/tool/remove_chart_from_dashboard.py tests/unit_tests/mcp_service/dashboard/test_layout_validation.py tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py
  • ruff check and ruff format --check pass for all changed Python files.
  • git diff --check
  • 19 standalone structural validator regression cases pass locally.
  • GitHub's Python unit-test matrix passes; the full workflow reruns for the latest commit.

ADDITIONAL INFORMATION

  • Has associated issue: SC-117987
  • Required feature flags
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

@dosubot dosubot Bot added change:backend Requires changing the backend dashboard Namespace | Anything related to the Dashboard labels Aug 20, 2026
@bito-code-review

bito-code-review Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #90c7af

Actionable Suggestions - 0
Review Details
  • Files reviewed - 5 · Commit Range: 348b8e4..348b8e4
    • superset/mcp_service/dashboard/layout_validation.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/update_dashboard.py
    • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@aminghadersohi
aminghadersohi force-pushed the aminghadersohi/ch117987/validate-dashboard-layout-updates branch 2 times, most recently from d184f9a to 0255d06 Compare August 20, 2026 18:16
Comment thread superset/mcp_service/dashboard/layout_validation.py Outdated
Comment thread superset/mcp_service/dashboard/layout_validation.py Outdated
Comment thread superset/mcp_service/dashboard/schemas.py Outdated
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.14815% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.85%. Comparing base (9781254) to head (037c7ea).
⚠️ Report is 31 commits behind head on master.

Files with missing lines Patch % Lines
...uperset/mcp_service/dashboard/layout_validation.py 87.59% 8 Missing and 8 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #43367       +/-   ##
===========================================
+ Coverage   66.81%   78.85%   +12.04%     
===========================================
  Files        2876     2878        +2     
  Lines      164454   168756     +4302     
  Branches    37960    38866      +906     
===========================================
+ Hits       109873   133076    +23203     
+ Misses      52388    33110    -19278     
- Partials     2193     2570      +377     
Flag Coverage Δ
hive 38.18% <13.33%> (+0.10%) ⬆️
mysql 58.49% <13.33%> (+0.73%) ⬆️
postgres 58.54% <13.33%> (+0.74%) ⬆️
presto 40.16% <13.33%> (+0.15%) ⬆️
python 83.35% <88.14%> (+24.12%) ⬆️
sqlite 58.23% <13.33%> (+0.75%) ⬆️
unit 73.74% <88.14%> (-26.26%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bito-code-review bito-code-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #2ded6f

Actionable Suggestions - 1
  • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py - 1
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py - 1
    • Test assertion mismatch with actual behavior · Line 141-147
Review Details
  • Files reviewed - 5 · Commit Range: 0255d06..b36ba19
    • superset/mcp_service/dashboard/layout_validation.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/update_dashboard.py
    • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread tests/unit_tests/mcp_service/dashboard/test_layout_validation.py Outdated
@bito-code-review

bito-code-review Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #2d7a94

Actionable Suggestions - 0
Review Details
  • Files reviewed - 6 · Commit Range: b36ba19..116e3e1
    • superset/mcp_service/dashboard/layout_validation.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/remove_chart_from_dashboard.py
    • superset/mcp_service/dashboard/tool/update_dashboard.py
    • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@gabotorresruiz gabotorresruiz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this fix @aminghadersohi, the failure mode is real and the validator is a solid piece of work. I dug in empirically: verified the hydration mechanism from the description (buildDashboardLayout indexes every CHART node, which suppresses the auto-place fallback for unreachable charts), ran the full mcp_service unit suite on this branch (3530 passed), confirmed the new regression test fails without the fix, and exercised update_dashboard live over MCP HTTP. The shape, graph, cycle, and reachability protections all behave as described, and invalid updates leave the stored layout untouched.

One thing is blocking for me: the parents consistency check rejects 5 of the 9 example dashboards shipped in this repo, and live it rejects a verbatim round-trip of a dashboard's own saved layout. Details inline, and happy to dig in with you on the normalization approach if useful.

Comment thread superset/mcp_service/dashboard/layout_validation.py Outdated
Comment thread superset/mcp_service/dashboard/layout_validation.py
@aminghadersohi
aminghadersohi force-pushed the aminghadersohi/ch117987/validate-dashboard-layout-updates branch from 116e3e1 to 037c7ea Compare August 21, 2026 20:51
@bito-code-review

bito-code-review Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #d59f57

Actionable Suggestions - 0
Additional Suggestions - 1
  • superset/mcp_service/dashboard/tool/remove_chart_from_dashboard.py - 1
    • Chart removal misses decimal-string IDs · Line 68-68
      The replacement of the `(chart_id, str(chart_id))` two-element check with `normalize_chart_id` silently drops charts whose `chartId` is a decimal string (e.g. `'10.0'`). `normalize_chart_id` only accepts `value.isdecimal()` which returns `False` for `'10.0'`, causing it to return `None` and never matching `chart_id`. This means charts with decimal-string chartIds in position_json will not be removed from the layout even though `slices` will be updated, leading to orphaned layout entries.
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset/mcp_service/dashboard/layout_validation.py - 1
Review Details
  • Files reviewed - 6 · Commit Range: b1406ef..037c7ea
    • superset/mcp_service/dashboard/layout_validation.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/remove_chart_from_dashboard.py
    • superset/mcp_service/dashboard/tool/update_dashboard.py
    • tests/unit_tests/mcp_service/dashboard/test_layout_validation.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers an incremental AI Review.

  • /review full - Manually triggers a full AI Review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@aminghadersohi aminghadersohi closed this by deleting the head repository Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:backend Requires changing the backend dashboard Namespace | Anything related to the Dashboard size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants