{"record":{"id":"50ea76b6ac4cdb12","repo":"apache/superset","slug":"chart-id-is-missing-form-data","errorCode":null,"errorMessage":"Chart ${id} is missing form_data","messagePattern":"Chart (.+?) is missing form_data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"superset-frontend/src/embedded/utils.ts","lineNumber":117,"sourceCode":"\n    if (!slice || !hasChartStateConverter(slice.viz_type)) {\n      return false;\n    }\n\n    if (chartId !== undefined && numericId !== chartId) {\n      return false;\n    }\n\n    return true;\n  });\n\n  const payloadPromises = chartEntries.map(async ([id, chart]) => {\n    const numericId = Number(id);\n    const slice = sliceEntities[id];\n\n    try {\n      if (!chart || typeof chart !== 'object' || !('form_data' in chart)) {\n        throw new Error(`Chart ${id} is missing form_data`);\n      }\n\n      const formData = getFormDataWithExtraFilters({\n        chart: { id: numericId, form_data: (chart as JsonObject).form_data },\n        chartConfiguration,\n        filters: getAppliedFilterValues(numericId),\n        colorScheme,\n        colorNamespace,\n        sliceId: numericId,\n        nativeFilters,\n        allSliceIds,\n        dataMask,\n        extraControls: {},\n      });\n\n      const chartState = chartStates[id]?.state;\n      const baseOwnState = dataMask[id]?.ownState || {};\n      const convertedState = chartState","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset-frontend/src/embedded/utils.ts#L99-L135","documentation":"In the embedded SDK bootstrap path, every chart entry taken from the dashboard layout must carry a form_data object so the embedded client can build its data query. The code iterates chartEntries from the layout and throws when an entry is not an object or lacks the form_data key. This guards against a corrupted or hand-edited layout where a chart slot has no associated form data.","triggerScenarios":"Loading an embedded dashboard whose positions/layout JSON contains a chart component without form_data; dashboards whose layout was edited by scripts or migrations that dropped form_data; chart entries keyed by id whose value is null.","commonSituations":"Imported dashboards with hand-crafted position_json; custom layout tooling that writes chart slots without form data; race where layout from a newer backend version is consumed by an older embedded bundle.","solutions":["Re-save the dashboard in the Superset UI so the layout and form_data are regenerated consistently.","Fix the layout JSON: every CHART component under positions must have its meta/form_data populated (or the chart re-added via Explore).","If you generate layouts programmatically, copy form_data from the chart's saved slice rather than writing an empty object.","Upgrade/downgrade mismatch: ensure the embedded frontend bundle matches the backend that produced the bootstrap payload."],"exampleFix":"// before\nconst payloadPromises = chartEntries.map(async ([id, chart]) => {\n  if (!chart || typeof chart !== 'object' || !('form_data' in chart)) {\n    throw new Error(`Chart ${id} is missing form_data`);\n  }\n  ...\n});\n\n// after\nconst payloadPromises = chartEntries\n  .filter(([id, chart]) => {\n    const ok = !!chart && typeof chart === 'object' && 'form_data' in chart;\n    if (!ok) logging.warn(`Skipping chart ${id}: missing form_data in layout`);\n    return ok;\n  })\n  .map(async ([id, chart]) => { ... });","handlingStrategy":"type-guard","validationCode":"function layoutChartsHaveFormData(\n  chartQueries: Record<string, unknown>,\n): boolean {\n  return Object.values(chartQueries).every(\n    c => !!c && typeof c === 'object' && 'form_data' in (c as object),\n  );\n}","typeGuard":"function hasFormData(chart: unknown): chart is { form_data: JsonObject } {\n  return (\n    !!chart &&\n    typeof chart === 'object' &&\n    'form_data' in chart &&\n    typeof (chart as { form_data: unknown }).form_data === 'object'\n  );\n}","tryCatchPattern":"chartEntries.forEach(([id, chart]) => {\n  if (!hasFormData(chart)) {\n    logging.warn(`Skipping embedded chart ${id}: no form_data in layout`);\n    return;\n  }\n  // build payload\n});","preventionTips":["Always create dashboard layouts through the Superset UI or the documented API so form_data stays in sync with charts.","When scripting layout edits, copy form_data from the chart resource rather than writing placeholder objects.","Add a dashboard-import validation step that checks every CHART slot has form_data."],"tags":["embedded","dashboard-layout","form-data","bootstrap"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}