Skip to content

fix(compose): add isImportantForBounds() to SentryTagModifierNode for compose-ui 1.11+#5672

Merged
antonis merged 4 commits into
getsentry:mainfrom
tsushanth:fix/sentry-compose-isimportantforbounds-1-11
Jul 2, 2026
Merged

fix(compose): add isImportantForBounds() to SentryTagModifierNode for compose-ui 1.11+#5672
antonis merged 4 commits into
getsentry:mainfrom
tsushanth:fix/sentry-compose-isimportantforbounds-1-11

Conversation

@tsushanth

Copy link
Copy Markdown
Contributor

Fixes #5662

Problem

compose-ui 1.11 added SemanticsModifierNode.isImportantForBounds() as an abstract method. SentryTagModifierNode was compiled against compose-ui 1.6.x, where the method does not exist, so its class bytecode has no implementation. When an accessibility client (TalkBack, UiAutomator2, adb shell uiautomator dump) traverses the Compose semantics tree at runtime with compose-ui 1.11+, the JVM cannot find the method and throws:

AbstractMethodError: abstract method "boolean androidx.compose.ui.node.SemanticsModifierNode.isImportantForBounds()"
    at SentryTagModifierNode (SentryModifier.kt)

Fix

Add fun isImportantForBounds(): Boolean = false to SentryTagModifierNode.

The override keyword is intentionally omitted because the method is absent from the compose-ui 1.6.x compile-time dependency — using override would fail to compile. The JVM satisfies the abstract-method contract at runtime via bytecode signature matching, regardless of whether the Kotlin compiler knew about the override at compile time.

SentryTagModifierNode stores only a semantic tag with no layout or visual effect, so false is the correct return value (it does not affect touch-bounds computation).

Testing

Verified no public API changes (./gradlew sentry-compose:apiCheck passes — SentryTagModifierNode is private, so no .api file update required). The fix applies cleanly to the existing compose-ui 1.6.x compile target without version bumps.

… compose-ui 1.11+

compose-ui 1.11 added SemanticsModifierNode.isImportantForBounds() as an
abstract method. SentryTagModifierNode was compiled against compose-ui 1.6.x,
where the method does not exist, so its bytecode lacks an implementation.
When an accessibility client (TalkBack, UiAutomator, adb uiautomator dump)
traverses the Compose semantics tree at runtime on 1.11+, the JVM cannot find
the method and throws AbstractMethodError.

Adding fun isImportantForBounds(): Boolean = false without the override keyword
(since the method is absent from the 1.6.x compile-time dependency) places the
method in the class bytecode. The JVM satisfies the abstract method requirement
via signature matching at runtime. SentryTagModifierNode stores only a semantic
tag with no layout/visual effect, so false is the correct return value.
Comment thread sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryModifier.kt Outdated

@antonis antonis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work on this @tsushanth 🙇
The fix LGTM 🚀

I reproduced the issue on a Pixel 8 Pro (Android 16) using sentry-samples-android. Repro patch (apply on main):

  diff --git a/sentry-samples/sentry-samples-android/build.gradle.kts b/sentry-samples/sentry-samples-android/build.gradle.kts
  index xxxxxxx..yyyyyyy 100644
  --- a/sentry-samples/sentry-samples-android/build.gradle.kts
  +++ b/sentry-samples/sentry-samples-android/build.gradle.kts
  @@ -178,6 +178,22 @@ sqldelight {
     }
   }

  +// Repro for #5662: run the app against compose-ui 1.11.x while sentry-compose stays
  +// compiled against its compileOnly compose-ui 1.6.3.
  +configurations.configureEach {
  +  resolutionStrategy.eachDependency {
  +    if (
  +      requested.group in
  +        setOf(
  +          "androidx.compose.ui",
  +          "androidx.compose.foundation",
  +          "androidx.compose.animation",
  +          "androidx.compose.runtime",
  +        )
  +    ) {
  +      useVersion("1.11.3")
  +    }
  +  }
  +}
  +
   dependencies {
     implementation(
       kotlin(Config.kotlinStdLib, org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
  diff --git a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
  index xxxxxxx..yyyyyyy 100644
  --- a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
  +++ b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
  @@ -87,7 +87,7 @@

       <activity
         android:name=".compose.ComposeActivity"
  -      android:exported="false" />
  +      android:exported="true" />

Confirmed that the fix on this PR resolves the crash 🎉

@antonis antonis merged commit 30862fc into getsentry:main Jul 2, 2026
64 checks passed
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.

AbstractMethodError: SemanticsModifierNode.isImportantForBounds() with sentry-compose on compose-ui 1.11+

3 participants