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

Image Query Context is null, when hitting API: http://localhost:8088/api/v1/chart/2030

Image Message after hitting API: http://localhost:8088/api/v1/chart/2030/data/

After Opening the Chart

Image Query Context is populated

Image 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:

  1. 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.
  2. 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  Join Discord Share on X

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, and chartIds 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  Join Discord Share on X

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?