Describe the bug
Not sure how to reproduce yet. It started after we updated the sdk to 6.16.0
Some of our users are getting a crash while inside a channel using a the compose ui component of MessageScreen. Since the error seems to be on an AnnotatedString and we don't have any customization using those, the issue is most likely in the sdk.
The stacktrace:
Fatal Exception: java.lang.IndexOutOfBoundsException
setSpan (-1 ... 6) starts before 0
android.text.SpannableStringInternal.checkRange (SpannableStringInternal.java:499)
android.text.SpannableStringInternal.setSpan (SpannableStringInternal.java:199)
android.text.SpannableStringInternal.setSpan (SpannableStringInternal.java:186)
android.text.SpannableString.setSpan (SpannableString.java:60)
androidx.compose.ui.text.platform.extensions.SpannableExtensions_androidKt$setFontAttributes$1.invoke (SpannableExtensions.android.kt:368)
androidx.compose.ui.text.platform.extensions.SpannableExtensions_androidKt$setFontAttributes$1.invoke (SpannableExtensions.android.kt:366)
androidx.compose.ui.text.platform.extensions.SpannableExtensions_androidKt.flattenFontStylesAndApply (SpannableExtensions.android.kt:450)
androidx.compose.ui.text.platform.extensions.SpannableExtensions_androidKt.setFontAttributes (SpannableExtensions.android.kt:366)
androidx.compose.ui.text.platform.extensions.SpannableExtensions_androidKt.setSpanStyles (SpannableExtensions.android.kt:258)
androidx.compose.ui.text.platform.AndroidParagraphIntrinsics. (AndroidParagraphIntrinsics.android.kt:121)
androidx.compose.ui.text.platform.AndroidParagraphHelper_androidKt.createCharSequence (AndroidParagraphHelper_android.kt:121)
androidx.compose.ui.text.platform.AndroidParagraphIntrinsics. (AndroidParagraphIntrinsics.android.kt:134)
androidx.compose.ui.text.platform.AndroidParagraphIntrinsics_androidKt.ActualParagraphIntrinsics (AndroidParagraphIntrinsics_android.kt:183)
androidx.compose.ui.text.ParagraphIntrinsicsKt.ParagraphIntrinsics (ParagraphIntrinsics.kt:126)
androidx.compose.ui.text.MultiParagraphIntrinsics. (MultiParagraphIntrinsics.kt:106)
androidx.compose.foundation.text.modifiers.MultiParagraphLayoutCache.setLayoutDirection (MultiParagraphLayoutCache.kt:301)
androidx.compose.foundation.text.modifiers.TextAnnotatedStringNode.setSubstitution (TextAnnotatedStringNode.kt:327)
androidx.compose.foundation.text.modifiers.MultiParagraphLayoutCache.layoutText-R2G3SPE (MultiParagraphLayoutCache.java:327)
androidx.compose.foundation.text.modifiers.MultiParagraphLayoutCache.layoutText-R2G3SPE$default (MultiParagraphLayoutCache.java:322)
androidx.compose.foundation.text.modifiers.MultiParagraphLayoutCache.layoutWithConstraints-K40F9xA (MultiParagraphLayoutCache.java:192)
androidx.compose.foundation.text.modifiers.TextAnnotatedStringNode.measure-3p2s80s (TextAnnotatedStringNode.kt:425)
androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0 (LayoutModifierNodeCoordinator.kt:190)
androidx.compose.foundation.layout.PaddingNode.measure-3p2s80s (Padding.kt:401)
androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0 (LayoutModifierNodeCoordinator.kt:190)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:169)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:168)
androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.kt:501)
androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe (SnapshotStateObserver.kt:460)
androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads (SnapshotStateObserver.kt:244)
androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release (OwnerSnapshotObserver.kt:124)
androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release (OwnerSnapshotObserver.kt:107)
androidx.compose.ui.node.MeasurePassDelegate.performMeasure-BRTryo0$ui_release (MeasurePassDelegate.kt:422)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:470)
androidx.compose.ui.node.MeasurePassDelegate.measure-BRTryo0 (MeasurePassDelegate.kt:450)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure (RowColumnMeasurePolicy.kt:126)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure$default (RowColumnMeasurePolicy.kt:77)
androidx.compose.foundation.layout.ColumnMeasurePolicy.measure-3p2s80s (Column.kt:208)
androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0 (InnerNodeCoordinator.kt:128)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:169)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:168)
androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.kt:501)
androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe (SnapshotStateObserver.kt:460)
androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads (SnapshotStateObserver.kt:244)
androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release (OwnerSnapshotObserver.kt:124)
androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release (OwnerSnapshotObserver.kt:107)
androidx.compose.ui.node.MeasurePassDelegate.performMeasure-BRTryo0$ui_release (MeasurePassDelegate.kt:422)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:470)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release (LayoutNode.kt:1212)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default (LayoutNode.kt:1205)
androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA (MeasureAndLayoutDelegate.kt:366)
androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded (MeasureAndLayoutDelegate.kt:566)
androidx.compose.ui.node.MeasureAndLayoutDelegate.onlyRemeasureIfScheduled (MeasureAndLayoutDelegate.kt:667)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:694)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:701)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:701)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtree (MeasureAndLayoutDelegate.kt:656)
androidx.compose.ui.platform.AndroidComposeView.forceMeasureTheSubtree (AndroidComposeView.android.kt:1576)
androidx.compose.ui.node.MeasurePassDelegate.markSubtreeAsNotPlaced (MeasurePassDelegate.kt:265)
androidx.compose.ui.node.Owner.forceMeasureTheSubtree$default (Owner.java:265)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:485)
androidx.compose.ui.node.MeasurePassDelegate.measure-BRTryo0 (MeasurePassDelegate.kt:450)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure (RowColumnMeasurePolicy.kt:126)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure$default (RowColumnMeasurePolicy.kt:77)
androidx.compose.foundation.layout.ColumnMeasurePolicy.measure-3p2s80s (Column.kt:208)
androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0 (InnerNodeCoordinator.kt:128)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:169)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:168)
androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.kt:501)
androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe (SnapshotStateObserver.kt:460)
androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads (SnapshotStateObserver.kt:244)
androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release (OwnerSnapshotObserver.kt:124)
androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release (OwnerSnapshotObserver.kt:107)
androidx.compose.ui.node.MeasurePassDelegate.performMeasure-BRTryo0$ui_release (MeasurePassDelegate.kt:422)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:470)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release (LayoutNode.kt:1212)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default (LayoutNode.kt:1205)
androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA (MeasureAndLayoutDelegate.kt:366)
androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded (MeasureAndLayoutDelegate.kt:566)
androidx.compose.ui.node.MeasureAndLayoutDelegate.onlyRemeasureIfScheduled (MeasureAndLayoutDelegate.kt:667)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:694)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:701)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtree (MeasureAndLayoutDelegate.kt:656)
androidx.compose.ui.platform.AndroidComposeView.forceMeasureTheSubtree (AndroidComposeView.android.kt:1576)
androidx.compose.ui.node.MeasurePassDelegate.markSubtreeAsNotPlaced (MeasurePassDelegate.kt:265)
androidx.compose.ui.node.Owner.forceMeasureTheSubtree$default (Owner.java:265)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:485)
androidx.compose.ui.node.MeasurePassDelegate.measure-BRTryo0 (MeasurePassDelegate.kt:450)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure (RowColumnMeasurePolicy.kt:126)
androidx.compose.foundation.layout.RowColumnMeasurePolicyKt.measure$default (RowColumnMeasurePolicy.kt:77)
androidx.compose.foundation.layout.RowMeasurePolicy.measure-3p2s80s (Row.kt:145)
androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0 (InnerNodeCoordinator.kt:128)
androidx.compose.foundation.layout.OffsetPxNode.measure-3p2s80s (Offset.kt)
androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0 (LayoutModifierNodeCoordinator.kt:190)
androidx.compose.foundation.layout.FillNode.measure-3p2s80s (Size.kt:721)
androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0 (LayoutModifierNodeCoordinator.kt:190)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:169)
androidx.compose.ui.node.MeasurePassDelegate$performMeasureBlock$1.invoke (MeasurePassDelegate.kt:168)
androidx.compose.runtime.snapshots.Snapshot.enter (Snapshot.java:150)
androidx.compose.runtime.snapshots.Snapshot$Companion.observe (Snapshot.kt:527)
androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe (SnapshotStateObserver.kt:460)
androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads (SnapshotStateObserver.kt:244)
androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release (OwnerSnapshotObserver.kt:124)
androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release (OwnerSnapshotObserver.kt:107)
androidx.compose.ui.node.MeasurePassDelegate.performMeasure-BRTryo0$ui_release (MeasurePassDelegate.kt:422)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:470)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release (LayoutNode.kt:1212)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default (LayoutNode.kt:1205)
androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA (MeasureAndLayoutDelegate.kt:366)
androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded (MeasureAndLayoutDelegate.kt:566)
androidx.compose.ui.node.MeasureAndLayoutDelegate.onlyRemeasureIfScheduled (MeasureAndLayoutDelegate.kt:667)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:694)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal (MeasureAndLayoutDelegate.kt:701)
androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtree (MeasureAndLayoutDelegate.kt:656)
androidx.compose.ui.platform.AndroidComposeView.forceMeasureTheSubtree (AndroidComposeView.android.kt:1576)
androidx.compose.ui.node.MeasurePassDelegate.markSubtreeAsNotPlaced (MeasurePassDelegate.kt:265)
androidx.compose.ui.node.Owner.forceMeasureTheSubtree$default (Owner.java:265)
androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0 (MeasurePassDelegate.kt:485)
androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release (LayoutNode.kt:1212)
androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA (MeasureAndLayoutDelegate.kt:364)
androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout-0kLqBqw (MeasureAndLayoutDelegate.kt:463)
androidx.compose.ui.platform.AndroidComposeView.measureAndLayout-0kLqBqw (AndroidComposeView.android.kt:1553)
androidx.compose.ui.layout.LayoutNodeSubcompositionsState$precompose$2.premeasure-0kLqBqw (SubcomposeLayout.kt:860)
androidx.compose.foundation.lazy.layout.PrefetchHandleProvider$HandleAndRequestImpl.performMeasure-BRTryo0 (LazyLayoutPrefetchState.kt:419)
androidx.compose.foundation.lazy.layout.PrefetchHandleProvider$HandleAndRequestImpl.execute (LazyLayoutPrefetchState.kt:385)
androidx.compose.foundation.lazy.layout.AndroidPrefetchScheduler.run (PrefetchScheduler.android.kt:122)
android.os.Handler.handleCallback (Handler.java:959)
android.os.Handler.dispatchMessage (Handler.java:100)
android.os.Looper.loopOnce (Looper.java:257)
android.os.Looper.loop (Looper.java:342)
android.app.ActivityThread.main (ActivityThread.java:9634)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:619)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:929)
SDK version
Expected behavior
To not have any crashes on MessageScreen
Device:
- Vendor and model: Samsung S20 FE and Samsung S21+
- Android version: 15 and 13 but mainly 15.