Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

GeoJSON source with dynamic: true and cluster: true renders no features

Open
#13,732 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Domain
frontend, web-dev

Research direction

Start in GeoJSONWorkerSource.loadData and GeoJSONRT.load, following how features are converted before reaching Supercluster when both dynamic and cluster are enabled. Reproduce the inline example and compare querySourceFeatures results for the three source configurations. Done means dynamic clustered sources render clusters and unclustered points, and updateData re-clusters updated features.

Written by the indexing model from the issue text.

Description

docs :scroll:
mapbox-gl-js version

3.31.0

Browser and version

Chrome 151, macOS

Expected behavior

A GeoJSON source with both dynamic: true and cluster: true renders clusters and unclustered points, the same as the source without dynamic, and updateData re-clusters the updated features.

Actual behavior

The source renders nothing. querySourceFeatures returns 0 features, whether the data is passed inline to addSource, set with setData, or added with updateData. The same data renders with cluster: true alone, and with dynamic: true alone.

In GeoJSONWorkerSource.loadData, when params.dynamic && params.cluster, the features passed to Supercluster come from this._dynamicIndex.getFeatures(). GeoJSONRT.load stores features after convertFeature, so Supercluster receives features in the internal geojson-vt format instead of GeoJSON Features with geometry.coordinates, and produces an empty index.

Link to the demonstration

Inline repro below.

Steps to trigger the unexpected behavior
const features = Array.from({ length: 1000 }, (_, i) => ({
  type: 'Feature',
  id: i,
  geometry: { type: 'Point', coordinates: [-122.4 + Math.random() * 0.2, 47.55 + Math.random() * 0.2] },
  properties: {},
}));

map.on('load', async () => {
  const results = {};
  for (const [name, options] of Object.entries({
    cluster: { cluster: true },
    dynamic: { dynamic: true },
    dynamicCluster: { dynamic: true, cluster: true },
  })) {
    map.addSource(name, { type: 'geojson', data: { type: 'FeatureCollection', features }, ...options });
    map.addLayer({ id: name, type: 'circle', source: name });
    await new Promise((resolve) => map.once('idle', resolve));
    results[name] = map.querySourceFeatures(name).length;
  }
  console.log(results);
});
  1. Run the snippet on a map centered at zoom 10.
  2. Observe cluster and dynamic report features; dynamicCluster reports 0 and nothing is drawn.
Relevant log output
{ cluster: 42, dynamic: 1061, dynamicCluster: 0 }

No errors are logged.

Dominant language
TypeScript
Stars
12.5k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mapbox/mapbox-gl-js

All issues in mapbox/mapbox-gl-js

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.