Bug description
We are trying to fetch chart data using /api/v1/chart/2910/data API, but we are getting 400 response with message "Chart has no query context saved. Please save the chart again". WorkAround: When we try hitting this API after manually opening the chart again, the API is able to fetch data. (We have around 100 charts because of which this workaround is not a feasible option for us)
P.S. We are using zip file to import dashboards
Screenshots/recordings
Query Context is null, when hitting API: http://localhost:8088/api/v1/chart/2030
Message after hitting API: http://localhost:8088/api/v1/chart/2030/data/
After Opening the Chart
Query Context is populated
Data is coming.
Superset version
4.0.2
Python version
3.9
Node version
16
Browser
Chrome
Additional context
No response
Checklist
- [x] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [x] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [ ] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
Comment From: dosubot[bot]
Hi @singhs124! I'm Dosu and I’m helping the superset team.
The 400 error with "Chart has no query context saved. Please save the chart again" occurs because the /api/v1/chart/{pk}/data/
endpoint depends on a saved query context for each chart. When dashboards are imported via zip files, the query context for charts may not be populated, which leads to this error until each chart is manually opened and saved in the UI. This is a known behavior: the query context is only generated and stored when a chart is saved through the Explore view or similar UI actions, not during import [source].
There is no built-in Superset command or API to bulk-generate or repair missing query contexts for charts after import. However, you can automate the process of opening and saving charts using browser automation tools like Cypress. Superset's own test suite includes Cypress scripts that programmatically open and save charts, which triggers the generation of the query context. For example, the saveChartToDashboard
and openExploreWithDashboardContext
functions in the Cypress test files automate these actions [source] [source].
To automate this for your environment, you could:
- Use Cypress or a similar tool to script logging in, opening each chart by ID, and saving it. This will populate the query context for each chart.
- Optionally, adapt the Cypress commands from Superset's test suite (see
visitChartById
,saveChartToDashboard
, etc.) to loop through your chart IDs [source].
There is also a Python-side approach: you could write a script that uses the Superset API to fetch each chart's form data, then POST it to the /api/v1/chart/{pk}
endpoint to trigger a save, but this is more complex and not officially documented.
In summary, the most practical workaround is to automate the "open and save" process using browser automation. There is no direct API or CLI command to bulk-populate missing query contexts after import. If you need help with a Cypress script template, let me know.
To reply, just mention my name @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
Comment From: singhs124
@dosu Please help me with Cypress Script template.
Comment From: dosubot[bot]
Here’s a Cypress script template to automate opening and saving charts in Superset, which will populate the missing query context for each chart. This template assumes you have a list of chart IDs and valid Superset credentials.
1. Cypress Setup
If you haven’t already, install Cypress in your project:
npm install cypress --save-dev
Create a new test file, for example: cypress/e2e/save_charts.cy.js
.
2. Script Template
// cypress/e2e/save_charts.cy.js
const supersetUrl = 'http://localhost:8088'; // Change if your Superset runs elsewhere
const username = 'YOUR_USERNAME';
const password = 'YOUR_PASSWORD';
const chartIds = [2030, 2910]; // Add all your chart IDs here
describe('Bulk open and save charts to populate query context', () => {
before(() => {
// Log in to Superset
cy.visit(`${supersetUrl}/login/`);
cy.get('input[name="username"]').type(username);
cy.get('input[name="password"]').type(password);
cy.get('button[type="submit"]').click();
// Wait for login to complete
cy.url().should('not.include', '/login');
});
chartIds.forEach(chartId => {
it(`Open and save chart ${chartId}`, () => {
// Visit the Explore page for the chart
cy.visit(`${supersetUrl}/explore/?slice_id=${chartId}`);
// Wait for the chart to load
cy.get('[data-test="query-save-button"]', { timeout: 20000 }).should('be.visible');
// Click the Save (overwrite) button
cy.get('[data-test="query-save-button"]').click();
cy.get('[data-test="save-overwrite-radio"]').check();
cy.get('[data-test="btn-modal-save"]').click();
// Wait for save to complete (optional: check for success notification)
cy.contains('Chart saved', { timeout: 10000 });
});
});
});
3. How to Run
Start your Superset instance and run Cypress:
npx cypress open
Select the test file you created and let it run. Cypress will log in, open each chart, and save it, which will generate the query context needed for the /api/v1/chart/{pk}/data/
endpoint.
4. Customization
- Update
supersetUrl
,username
,password
, andchartIds
as needed. - If you use SSO or a different login flow, adjust the login steps accordingly.
- You can expand the script to read chart IDs from a file or API if needed.
References
This template is based on patterns and selectors used in Superset’s own Cypress tests, such as the use of [data-test="query-save-button"]
and the save modal flow, as seen in the official test files (example).
If you need to save charts to a specific dashboard or want to automate more complex flows, you can adapt functions like saveChartToDashboard
from Superset’s test suite (example).
Let me know if you need a version that saves to dashboards or handles other custom flows!
To reply, just mention my name @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
Comment From: rusackas
CC @villebro @michael-s-molina @mistercrunch who have been in discussion about missing/outdated query contexts and how to (potentially) automate (re)populating them.
Comment From: mistercrunch
[workaround] I think re-saving the chart would fix it (?)
There's a wider refactor people have been talking about to fix this. The TLDR on the issue is that the mapping between the chart definition to the query object can only be done on the frontend (each plugin has it's own js logic to do this), and that in some cases the backend needs to run the query behind a given chart, like in this instance here, but more broadly in alerts & reports.
I think there's a new migration in master that may help, though unclear if it'll generate a query_context if it doesn't exist.
I think the plan is to run js in a subprocess on the backend (?)
Comment From: singhs124
Hi, Do we have anything for this issue?