{"record":{"id":"a2debd553704c134","repo":"apache/superset","slug":"position-of-picked-data-is-required","errorCode":null,"errorMessage":"Position of picked data is required","messagePattern":"Position of picked data is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"superset-frontend/plugins/preset-chart-deckgl/src/utils/crossFiltersDataMask.ts","lineNumber":108,"sourceCode":"  positions?: [number, number][];\n  spatialData: SpatialData;\n  positionBounds?: PositionBounds;\n}) => {\n  const {\n    lonCol,\n    latCol,\n    lonlatCol,\n    geohashCol,\n    reverseCheckbox,\n    type,\n    delimiter,\n  } = spatialData;\n  let values: (string | number | [number, number] | [number, number][])[] = [];\n  let filters: QueryObjectFilterClause[] = [];\n  let customColumnLabel;\n\n  if (!position && !positions && !positionBounds)\n    throw new Error('Position of picked data is required');\n\n  switch (type) {\n    case spatialTypes.latlong: {\n      if (lonCol != null && latCol != null) {\n        const cols = [lonCol, latCol];\n\n        if (positions && positions.length > 0) {\n          values = positions;\n          customColumnLabel = cols.join(', ');\n\n          filters = [\n            {\n              col: lonCol,\n              op: 'IN',\n              val: positions.map(pos => pos[0]),\n            },\n            {\n              col: latCol,","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset-frontend/plugins/preset-chart-deckgl/src/utils/crossFiltersDataMask.ts#L90-L126","documentation":"Thrown by the deck.gl cross-filters data-mask builder when a picked (clicked) chart element carries none of position, positions, or positionBounds. Cross-filtering a deck.gl layer works by converting the clicked geometry into filter values over the spatial columns; with no position data on the pick payload there is nothing to filter on and the mask cannot be built.","triggerScenarios":"Clicking (cross-filtering) a deck.gl chart object whose picked datum lacks position/positions/positionBounds — e.g. a polygon pick that returned only bounds under a different key, a null island point, or programmatic calls to the mask builder with a synthetic pick object.","commonSituations":"Cross-filter enabled on layers whose data rows contain null coordinates; plugins/forks adding layer types without populating pick positions; version changes to the pick payload shape.","solutions":["Check the layer's data: rows with null/missing coordinates should be filtered (the layers already add IS NOT NULL filters — verify they are applied).","If developing a custom layer, ensure onClick picks include position (point), positions (paths), or positionBounds (polygons) before invoking the mask builder.","Disable cross-filter on the chart if the layer type does not carry positional picks."],"exampleFix":"// before\nconst mask = getCrossFilterDataMask(picked); // picked has no geometry\n\n// after\nif (!picked.position && !picked.positions && !picked.positionBounds) {\n  return; // nothing filterable was picked\n}\nconst mask = getCrossFilterDataMask(picked);","handlingStrategy":"validation","validationCode":"if (!picked.position && !picked.positions && !picked.positionBounds) {\n  return; // nothing filterable\n}\nconst mask = getCrossFilterDataMask(picked);","typeGuard":"const hasPickGeometry = (p: unknown): boolean =>\n  p != null && Boolean((p as any).position || (p as any).positions || (p as any).positionBounds);","tryCatchPattern":"try { applyCrossFilter(getCrossFilterDataMask(picked)); } catch (e) { if (e.message === 'Position of picked data is required') console.warn('non-geometric pick ignored'); else throw e; }","preventionTips":["Populate position data on picks in custom layers","Filter null-coordinate rows upstream so picks always carry geometry"],"tags":["deckgl","cross-filter","spatial","validation"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}