Skip to content

fix(chart): load viz_type from request params when creating chart via API#40536

Merged
hainenber merged 5 commits into
masterfrom
fix-viz-type-in-api-calls
May 31, 2026
Merged

fix(chart): load viz_type from request params when creating chart via API#40536
hainenber merged 5 commits into
masterfrom
fix-viz-type-in-api-calls

Conversation

@rusackas
Copy link
Copy Markdown
Member

SUMMARY

Adopts and fixes #31929 (originally by @hdahme, whose fork was subsequently archived).

When creating a chart via the API, the viz_type field was not being extracted from the JSON-encoded params string. This meant that charts created programmatically with params set (but without an explicit top-level viz_type) ended up with a blank/wrong chart type.

Changes in superset/commands/chart/create.py:

  • In CreateChartCommand.__init__, if params is present, parse it and copy viz_type into the top-level properties so the model gets the correct chart type.
  • Moved import json to module level using from superset.utils import json (project convention).
  • Removed the vacuous try/except JSONDecodeError as ex: raise ex antipattern — let the exception propagate naturally.
  • Added isinstance(params, dict) guard to prevent TypeError when the params JSON is not an object (e.g. an array or scalar).

TESTING INSTRUCTIONS

pytest tests/integration_tests/charts/commands_tests.py -k "viz_type" -v

The integration test at tests/integration_tests/charts/commands_tests.py already covers the expected behaviour: a chart created with params={"viz_type": "new_viz_type"} should have chart.viz_type == "new_viz_type".

ADDITIONAL INFORMATION

🤖 Generated with Claude Code

hdahme and others added 4 commits May 29, 2026 20:53
…mmand

- Move json import to module level (from superset.utils import json)
- Remove redundant try/except that only re-raised the exception
- Add isinstance(params, dict) guard to prevent TypeError when params
  JSON is not an object (e.g. a list or string)
- Fix single-quote style to match project conventions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dosubot dosubot Bot added the api Related to the REST API label May 30, 2026
@github-actions github-actions Bot removed the api Related to the REST API label May 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Congrats on making your first PR and thank you for contributing to Superset! 🎉 ❤️

Please read our New Contributor Welcome & Expectations guide.

We hope to see you in our Slack community too! Not signed up? Use our Slack App to self-register.

@rusackas rusackas added the merge-if-green If approved and tests are green, please go ahead and merge it for me label May 30, 2026
Comment thread superset/commands/chart/create.py Outdated
Comment on lines +49 to +50
if isinstance(params, dict) and "viz_type" in params:
self._properties["viz_type"] = params["viz_type"]
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.

Suggestion: This unconditionally overwrites a user-supplied top-level chart type whenever params contains viz_type. If both are present but differ, the explicit API field is silently ignored and the chart can be created with the wrong visualization type. Only copy from params when the top-level field is missing. [incorrect condition logic]

Severity Level: Major ⚠️
- ❌ POST /api/v1/chart persists unexpected viz_type from params.
- ⚠️ Programmatic chart creation can silently ignore explicit viz_type.
- ⚠️ Generated charts may render with inconsistent visualization type.
Steps of Reproduction ✅
1. Send a POST request to the chart creation API `POST /api/v1/chart/` handled by
`ChartRestApi.post()` in `superset/charts/api.py` (around lines 359–366 per `add` method
snippet).

2. In the JSON body, provide a valid top-level `viz_type`, e.g. `"viz_type": "bar"`, and a
`params` string whose JSON contains a conflicting `viz_type`, e.g. `"params":
"{\"viz_type\": \"line\"}"`. This request payload is loaded by `ChartPostSchema` in
`superset/charts/schemas.py:28-53`, which validates the top-level `viz_type` as a string
and `params` as JSON.

3. After schema validation, `ChartRestApi.post()` calls `CreateChartCommand(item).run()`
(see `superset/charts/api.py` snippet lines 20-27). Inside `CreateChartCommand.__init__`
in `superset/commands/chart/create.py:44-50`, `self._properties` is set to the validated
data, then `params_str` is JSON-decoded and, because the decoded dict has `"viz_type":
"line"`, the unconditional assignment at lines 49-50 overwrites the already-validated
top-level `"viz_type": "bar"` with `"line"`.

4. `CreateChartCommand.run()` then calls `ChartDAO.create(attributes=self._properties)`
(create.py:52-57), which persists a `Slice` model (`superset/models/slice.py:68-82`) with
`viz_type="line"`. Fetching or rendering this chart later (e.g. via explore or GET
endpoints) shows `viz_type="line"`, demonstrating that the explicit API field was silently
ignored whenever `params` also contained `viz_type`.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/commands/chart/create.py
**Line:** 49:50
**Comment:**
	*Incorrect Condition Logic: This unconditionally overwrites a user-supplied top-level chart type whenever `params` contains `viz_type`. If both are present but differ, the explicit API field is silently ignored and the chart can be created with the wrong visualization type. Only copy from `params` when the top-level field is missing.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch — fixed in bae380f. Switched from direct assignment to setdefault() so the top-level viz_type wins when both it and a viz_type inside params are supplied.

@bito-code-review
Copy link
Copy Markdown
Contributor

The PR comment file contains only the header row and no additional data. I cannot analyze or provide information about specific comments or suggestions in this PR.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.99%. Comparing base (43c3c06) to head (bae380f).
⚠️ Report is 15 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #40536      +/-   ##
==========================================
- Coverage   64.00%   63.99%   -0.02%     
==========================================
  Files        2620     2637      +17     
  Lines      140974   141658     +684     
  Branches    32527    32567      +40     
==========================================
+ Hits        90236    90652     +416     
- Misses      49187    49451     +264     
- Partials     1551     1555       +4     
Flag Coverage Δ
hive 39.68% <20.00%> (+0.21%) ⬆️
mysql 58.50% <100.00%> (+0.02%) ⬆️
postgres 58.58% <100.00%> (+0.02%) ⬆️
presto 41.30% <20.00%> (+0.19%) ⬆️
python 60.08% <100.00%> (+<0.01%) ⬆️
sqlite 58.24% <100.00%> (+0.02%) ⬆️
unit 100.00% <ø> (ø)

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

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review Agent Run #21ab12

Actionable Suggestions - 1
  • superset/commands/chart/create.py - 1
Review Details
  • Files reviewed - 1 · Commit Range: ffde065..8328023
    • superset/commands/chart/create.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ 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 on lines +47 to +48
if params_str := self._properties.get("params"):
params = json.loads(params_str)
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.

Uncaught JSON parse exception

Wrap json.loads(params_str) in a try-except block to catch JSONDecodeError and convert it into a ChartInvalidError, ensuring malformed JSON is handled gracefully.

Code Review Run #21ab12


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The marshmallow schema for chart creation (superset/charts/schemas.py) already applies validate=utils.validate_json to the params field before the request reaches CreateChartCommand.__init__, so json.loads here cannot raise JSONDecodeError in normal operation. Adding a catch would be dead code — declining this one.

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.

The suggestion to add a try-except block around json.loads(params_str) is valid and should be applied. The suggestion addresses a potential edge case where params_str might be malformed JSON, which could cause a runtime error. Even though the schema already validates params, adding a try-except block ensures robustness in case of unexpected input. This is a defensive programming practice that improves code reliability.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Standing by rusackas's assessment — the Marshmallow schema in superset/charts/schemas.py applies validate=utils.validate_json to params before this command is ever constructed, so json.loads here can only fail if something bypasses the schema layer. Adding a try-except would be dead code that obscures that invariant. Declining.

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.

This question isn’t related to the pull request. I can only help with questions about the PR’s code or comments.

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.

The /resolve command is not supported on inline comments. Please use it in a top-level comment instead.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Closing this thread. The Marshmallow schema in superset/charts/schemas.py applies validate=utils.validate_json to the params field before CreateChartCommand is ever constructed, so json.loads(params_str) cannot receive malformed JSON. No try/except needed. Bito's subsequent replies are loop artifacts from /resolve not being supported on inline comments.

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.

This question isn’t related to the pull request. I can only help with questions about the PR’s code or comments.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thread closed. The Marshmallow schema in superset/charts/schemas.py applies validate=utils.validate_json to the params field before CreateChartCommand is ever constructed, so json.loads(params_str) cannot raise JSONDecodeError here. No try/except is needed. Bito's replies are loop artifacts from /resolve not being supported on inline comments.

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.

This question isn’t related to the pull request. I can only help with questions about the PR’s code or comments.

If a caller supplies viz_type at the top level and also embeds it in
the params JSON, the explicit field should take precedence. Switching
from a direct assignment to setdefault() ensures the params value is
only used when no top-level viz_type was provided.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented May 30, 2026

Code Review Agent Run #bf6f4e

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: 8328023..bae380f
    • superset/commands/chart/create.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ 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

@hainenber hainenber merged commit 5857456 into master May 31, 2026
59 checks passed
@hainenber hainenber deleted the fix-viz-type-in-api-calls branch May 31, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-if-green If approved and tests are green, please go ahead and merge it for me size/XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants