Conversation
Member
|
@SRWieZ there are merge conflicts. Could you resolve? |
Unkeyed EDGE nodes use positional IDs. Removing conditional siblings can therefore assign an old ID to a different element type. NodeView keyed only on ID, so Compose could reuse incompatible remembered state and crash in collectIsPressedAsState. Include the node type in the Compose key, matching the native tree differ's structural identity check. Add an Android instrumentation regression that changes a positional node from text to a pressable with feedback and reproduces the original crash before the fix.
SRWieZ
force-pushed
the
fix/android-node-identity
branch
from
October 3, 2026 13:39
714b66c to
6c85369
Compare
Member
Author
|
@simonhamp conflicts resolved: rebased on main. |
simonhamp
approved these changes
Oct 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's wrong
On Android, removing conditional siblings can crash the app when an unkeyed element's positional node ID is reused by a different element type.
NodeViewkeys its Compose subtree withnode.id, but the native tree differ treats an ID and type change as a structural replacement. When a re-render removes elements above a pressable, the pressable can inherit the positional ID previously occupied by a text node. Compose then reuses incompatible remembered slots and crashes while collecting the pressed state:Minimum repro:
Re-render with
$showOptions = false. The trailing pressable takes the positional ID formerly used by the text node and Android crashes.What this does
NodeViewby bothnode.idandnode.type, matching the existing structural identity check in the native tree differ.native:keybehavior is unchanged.ClassCastExceptionbefore the one-line fix.Verification
NodeViewIdentityTestfails with theComposableLambdaImpl cannot be cast to MutableStatecrash above.NodeViewIdentityTestpasses on an Android API 33 emulator../gradlew assembleDebug assembleDebugAndroidTestpasses../gradlew testDebugUnitTestpasses.No screenshot — this is a deterministic runtime crash rather than a visual rendering bug; the instrumentation regression captures the failure directly.