Skip to content

A tile stays blank when it is recreated while its aborted request is still ending #2290

Description

@greensopinion

What is the bug?

With NetworkTileProvider and abortObsoleteRequests: true (the default), a tile can stay blank and never fill in.

When a tile is pruned while its request is in flight, the request is aborted. The aborted load then completes with a transparent image, and NetworkTileImageProvider removes it from Flutter's ImageCache only after the RequestAbortedException arrives. If a new tile with the same URL is created before that, it gets the pending load from the ImageCache and shows the transparent image. It stays blank until it is pruned. Zooming in or out and back again makes the area blank again, as long as the tile is recreated in that interval.

I found it on an iPhone 13 while testing the pitch changes in #2284: after zooming out a little, one tile stayed blank. At pitch more tiles are pruned and recreated during camera changes, so the bug happens more often there, but the cause is on master. It doesn't apply on the web, where requests aren't aborted.

flutter_map-cancelled-tile

How can we reproduce it?

#2286 adds test/layer/tile_layer/tile_provider/network_image_provider_abort_test.dart. On master, without the fix, it fails with Expected: <2>, Actual: <1>: the test aborts a request and requests the same URL again before the abort error arrives, and the second request is never made because the second tile receives the aborted load.

Do you have a potential solution?

Yes, #2286. When the abort trigger completes and the load hasn't finished, NetworkTileImageProvider evicts the load from the ImageCache immediately, instead of waiting for the abort error. A tile created after the abort then starts its own request.

I wrote this with Claude Code (Claude Opus 5.5).

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

    No labels
    No labels

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions