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

MosaicLayer throws on every update after a source fails to load

Open Beginner friendly
#798 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript

Research direction

Start in packages/deck.gl-geotiff/src/mosaic-layer/mosaic-layer.ts at the renderSubLayers logic referenced in the issue, and compare its handling of missing tile content with RasterTileLayer._renderSubLayers. Add or adapt a LayerManager test that rejects getSource, waits for the tile to settle, then updates again. Done means the update no longer throws and later loaded sources still draw.

Written by the indexing model from the issue text.

Description

[!NOTE]
This issue was written by Claude (Claude Code) on behalf of @kylebarron, not by @kylebarron.

Problem

When a source's getSource rejects, for example because its GeoTIFF returns 404, MosaicLayer breaks:

  • Every later update of its inner TileLayer throws TypeError: Cannot destructure property 'source' of 'data' as it is null. While the map pans, that's about one error per frame.
  • The TileLayer stops drawing the sources that load after the failure.

Found in usgs-topo (kylebarron/usgs-topo#54). One sheet in a view of Twin Lakes, CA, is in the USGS catalog but not in its bucket. In headless Chrome, that view logged 334 errors over 12 short drags, and none of the 7.5' sheets in that MosaicLayer drew.

Seen with deck.gl-raster 0.9.0 and deck.gl 9.4.0. main (4b03f23) has the same code.

Cause

  1. deck.gl settles a tile whose getTileData rejected: it sets content to null, marks the tile loaded, and calls onError (tile-2d-header.ts#L150-L170). Its comment says this is on purpose, and deck.gl 9.1 and 9.2 do the same.
  2. TileLayer._onTileError clears tile.layers and asks for an update (tile-layer.ts#L333-L338). renderLayers then calls renderSubLayers for the loaded tile with data: tile.content, which is null (#L411-L429).
  3. MosaicLayer's renderSubLayers destructures props.data without a check (mosaic-layer.ts#L286-L290). TypeScript doesn't flag it, because deck.gl types that data as DataT, not DataT | null (tile-layer.ts#L71-L78).

The throw comes before renderLayers sets tile.layers, so every later update renders that tile again and throws again. And since renderLayers throws, CompositeLayer._postUpdate never stores the new sublayers (composite-layer.ts#L252-L260). The TileLayer keeps drawing the sublayers of its last good render, which lack the sources that loaded since.

Both effects last as long as the failed tile stays in the tileset's cache. renderLayers walks every cached tile, not only the visible ones (tile-layer.ts#L408, tileset-2d.ts#L616). With the default maxCacheSize, five times the selected tiles (#L591-L594), a failed tile can stay cached long after it leaves the view.

RasterTileLayer._renderSubLayers already handles a tile without content (raster-tile-layer.ts#L546-L548).

Workaround

Make getSource resolve instead of reject, for example to null, and draw nothing for that data in renderSource. usgs-topo does this in kylebarron/usgs-topo#54.

Proposed fix

  1. Return nothing for a tile without content:

    renderSubLayers: (props) => {
      // A tile whose `getSource` rejected settles with `null` content.
      if (!props.data) {
        return null;
      }
      const { source, signal, data: userData } = props.data;
      return renderSource(source, { data: userData, signal });
    },
    

    The failure is still reported once per load: through onSourceError if it's set, and otherwise by TileLayer's default onTileError, which logs it.

  2. Test it: render a MosaicLayer whose getSource rejects through a LayerManager, with a viewport over the source. Wait for the tile to settle, then update again. usgs-topo has a test like this (cog-mosaic-open.test.ts#L97-L129).

🤖 Written by Claude Code

Dominant language
TypeScript
Stars
231
Forks
34
Avg merge
1d 8h
Merged PRs (30d)
71

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

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 developmentseed/deck.gl-raster

All issues in developmentseed/deck.gl-raster

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.