Skip to content

fix: avoid zero-size crash in rememberComposeBitmapDescriptor when used inside Clustering - #963

Open
kikoso wants to merge 1 commit into
mainfrom
fix/marker-composable-zero-size-in-clustering
Open

fix: avoid zero-size crash in rememberComposeBitmapDescriptor when used inside Clustering#963
kikoso wants to merge 1 commit into
mainfrom
fix/marker-composable-zero-size-in-clustering

Conversation

@kikoso

@kikoso kikoso commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • rememberComposeBitmapDescriptor hosted its throwaway rendering ComposeView on LocalView.current, which can itself be mid-attach with no Android layout pass performed on it yet — this happens when the function is called from content composed inside Clustering's clusterItemContent, since the InvalidatingComposeView hosting that content is still being attached to its own parent at that exact point. measure() returned a 0x0 size and the function threw IllegalStateException.
  • Fix hosts the throwaway view on the window's root view instead, which is already laid out by the time any marker/cluster content is composed. setParentCompositionContext keeps the composition correctly scoped to the caller regardless of which Android View it's physically parented under, so this is safe.
  • Note: this fixes rememberComposeBitmapDescriptor itself. Nesting the full MarkerComposable (not just rememberComposeBitmapDescriptor) inside Clustering's clusterItemContent is a separate, unsupported combination — MarkerComposable also places a Marker node via MapApplier, which doesn't exist in that composition context, and will still throw IllegalStateException: Invalid applier regardless of this fix.

Fixes #694

Test plan

  • Added testClusterItemContentUsingRememberComposeBitmapDescriptorDoesNotCrash to GoogleMapViewClusteringTests, calling rememberComposeBitmapDescriptor from inside clusterItemContent — reproduces the crash pre-fix, passes post-fix.
  • Ran GoogleMapViewClusteringTests on a physical device (Pixel 4, API 33): all 3 tests pass.
  • Manually reproduced the original crash on-device (IllegalStateException: The ComposeView was measured to have a width or height of zero) and confirmed it no longer occurs after the fix.

…ed inside Clustering

rememberComposeBitmapDescriptor hosted its throwaway rendering
ComposeView on LocalView.current, which can itself be mid-attach with
no Android layout pass performed on it yet -- notably when this is
called from content composed inside Clustering's clusterItemContent,
whose InvalidatingComposeView is still being attached to its own
parent at that point. That caused measure() to return a 0x0 size and
throw IllegalStateException.

Host the throwaway view on the window's root view instead, which is
already laid out by the time any marker/cluster content is composed.
setParentCompositionContext keeps the composition correctly scoped to
the caller regardless of which Android View it's physically parented
under, so this is safe.

Fixes #694
@kikoso
kikoso marked this pull request as ready for review August 14, 2026 06:38
@googlemaps-bot

Copy link
Copy Markdown
Contributor

Code Coverage

Overall Project 25.82%

There is no coverage information present for the Files changed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MarkerComposable throw Fatal Exception: java.lang.IllegalArgumentException: width and height must be > 0

3 participants