Skip to content

[Bug] Stale async iconAtlas completion destroys the currently active texture (v9.4.0) #10827

Description

@vaduga

Description

When IconLayer.iconAtlas changes while an earlier load is pending, resolving the loads out of order can destroy the newer, active atlas texture, even though the older result is subsequently discarded.
All icons using that atlas become corrupted: SVG icons appear as vertical stripes, and transparent atlas cells appear as filled squares.

Originally observed during initial rendering or refresh. The issue reproduces in Firefox/Chromium using:

  • @deck.gl/core and @deck.gl/layers: 9.4.0
  • luma.gl: 9.4.2

The reproduction uses ordinary layer props and Deck.setProps(). Controlled promises make the completion order deterministic. A preceding BitmapLayer binds a distinctive texture to make the incorrect sampling visible.
The apparent cause is in ComponentState._watchPromise: _postProcessValue runs before _setAsyncPropValue checks the completion’s load count. Consequently, the stale completion invokes the release hook on the active texture before its result is rejected.
The proposed fix checks whether the request is still current before invoking _postProcessValue:

- if (!this.component) {
+ if (!this.component || loadCount !== asyncProp.pendingLoadCount) {
    return;
  }
  data = this._postProcessValue(asyncProp, data);

Reproduction source and proposed fix demo. Both demos use the same scene and dependencies; the fixed bundle applies only the guard above.

Flavors

React

Expected Behavior

An older atlas completion should be ignored before resource release or transformation. The newer atlas should remain valid, the SVG should retain its appearance, and the blank cell should remain transparent.

Steps to Reproduce

I created a standalone reproduction repository containing the full source, pinned dependencies, and a proposed fix demo.

Both versions are hosted on GitHub Pages:

  1. Open the original reproduction with WebGL enabled.
  2. Click 1. Resolve newer atlas first. This completes the newer request while the older request remains pending.
  3. Click 2. Resolve older atlas afterwards. This completes the stale request.
  4. Open the proposed fix demo and repeat the same sequence.

Both demos use the same scene and dependencies. The fixed version adds the proposed guard in ComponentState._watchPromise.

Environment

  • Framework version: deck.gl@9.4.0
  • Browser: Chrome/Firefox
  • OS: Cachy OS

Logs

No response

Activity

  1. changed the title [-][Bug] Stale async iconAtlas completion destroys the currently active texture[/-] [+][Bug] Stale async iconAtlas completion destroys the currently active texture (v9.4.0)[/+] on Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions