{"record":{"id":"73ab60529b73f45c","repo":"apache/superset","slug":"spatial-configuration-is-required-for-this-chart","errorCode":null,"errorMessage":"Spatial configuration is required for this chart","messagePattern":"Spatial configuration is required for this chart","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"superset-frontend/plugins/preset-chart-deckgl/src/layers/spatialUtils.ts","lineNumber":123,"sourceCode":"  filters: QueryObjectFilterClause[],\n): QueryObjectFilterClause[] {\n  if (!spatial) return filters;\n\n  const spatialColumns = getSpatialColumns(spatial);\n  const nullFilters: QueryObjectFilterClause[] = spatialColumns.map(column => ({\n    col: column,\n    op: 'IS NOT NULL',\n    val: null,\n  }));\n\n  return [...filters, ...nullFilters];\n}\n\nexport function buildSpatialQuery(formData: SpatialFormData) {\n  const { spatial, size: metric, tooltip_contents } = formData;\n\n  if (!spatial) {\n    throw new Error(`Spatial configuration is required for this chart`);\n  }\n  return buildQueryContext(formData, {\n    buildQuery: baseQueryObject => {\n      const spatialColumns = getSpatialColumns(spatial);\n      let columns = [...(baseQueryObject.columns || []), ...spatialColumns];\n      const metrics = metric ? [metric] : [];\n\n      columns = addTooltipColumnsToQuery(columns, tooltip_contents);\n\n      const filters = addSpatialNullFilters(\n        spatial,\n        ensureIsArray(baseQueryObject.filters || []),\n      );\n\n      const orderby = metric\n        ? normalizeOrderBy({ orderby: [[metric, false]] }).orderby\n        : baseQueryObject.orderby;\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset-frontend/plugins/preset-chart-deckgl/src/layers/spatialUtils.ts#L105-L141","documentation":"Thrown by buildSpatialQuery in the deck.gl spatial utilities when formData.spatial is absent. This helper builds the query context for spatially-driven layers (it later delegates to getSpatialColumns), and without a spatial configuration there are no coordinate columns to request, so it refuses up front.","triggerScenarios":"Calling buildSpatialQuery with form data whose spatial field is undefined — a layer chart saved before the spatial control was set, or a query context assembled programmatically without the key.","commonSituations":"Half-configured deck.gl charts on dashboards; imported dashboards with stripped spatial params; code paths that conditionally attach spatial and skip it for edge-case form states.","solutions":["Configure the chart's spatial control in Explore (latlong/delimited/geohash plus its column) and save.","Verify saved chart params include a populated spatial object; repair via PUT /api/v1/chart/{id}.","Guard in code: check formData.spatial before invoking buildSpatialQuery and surface a config prompt instead."],"exampleFix":"// before\nbuildSpatialQuery({ ...formData }); // spatial undefined\n\n// after\nif (!formData.spatial) {\n  throw new Error('Configure spatial encoding in the chart before querying');\n}\nbuildSpatialQuery(formData);","handlingStrategy":"validation","validationCode":"if (!formData.spatial) {\n  throw new Error('Spatial configuration missing in form data');\n}\nbuildSpatialQuery(formData);","typeGuard":"const hasSpatialConfig = (fd: SpatialFormData): boolean => Boolean(fd.spatial?.type);","tryCatchPattern":"try { buildSpatialQuery(formData); } catch (e) { if (e.message.includes('Spatial configuration is required')) showConfigToast(e.message); else throw e; }","preventionTips":["Check spatial before any buildSpatialQuery call in custom layers","Keep chart params and layer code in sync on the spatial schema"],"tags":["deckgl","spatial","buildquery","validation"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}