Skip to content

NoSuchMethodError in SentryTraced on Compose < 1.8 (inlined Box pulls in newer internals) #5885

Description

@runningcode

Summary

sentry-compose ships bytecode that references Jetpack Compose internal APIs newer than the SDK's own declared Compose floor (androidxCompose = "1.6.3" in gradle/libs.versions.toml). Apps resolving an older Compose crash with NoSuchMethodError when composing SentryTraced.

Sentry issue: SDK-CRASHES-JAVA-48AR — 157 occurrences, first seen 2026-03-19, reported on release 8.51.0.

Root cause

androidx.compose.foundation.layout.Box is an inline composable. The Compose compiler bakes its body into our bytecode, so sentry-compose calls Compose internals directly rather than calling BoxKt.Box. The published 8.51.0 SentryComposeTracingKt contains zero BoxKt.Box call sites and instead references:

Symbol First available in
BoxKt.maybeCachedBoxMeasurePolicy foundation-layout 1.7.0
Composer.shouldExecute runtime 1.8.0

Neither exists on Compose 1.6.x, so the call fails at runtime at the SentryTraced frame.

SentryUserFeedbackButtonKt is affected the same way (it also emits shouldExecute / materializeModifier).

How it regressed

sentry-compose/build.gradle.kts declares compileOnly(libs.androidx.compose.material3). In #5017 ("Convert main screen to Jetpack Compose" — a samples refactor) material3 was bumped 1.2.1 -> 1.4.0. material3 1.4.0 transitively pulls foundation-layout 1.8.1 and runtime 1.9.0 onto sentry-compose's compile classpath, silently raising the floor of the inlined code.

Confirmed by bisecting published artifacts on Maven Central:

  • 8.31.0 and earlier -> rememberBoxMeasurePolicy (works on 1.6.x)
  • 8.32.0 onward -> maybeCachedBoxMeasurePolicy + shouldExecute

Note on the Seer suggestion

Seer's autofix suggests removing propagateMinConstraints = true from the Box in SentryTraced. This is incorrect. BoxKt's public signature is byte-for-byte identical from foundation-layout 1.5.4 through 1.11.2 — propagateMinConstraints has always been a parameter. Removing it would change layout behavior (regressing #2637) without fixing the crash.

Proposed fix

Decouple sentry-compose's compile-time Compose floor from material3. Add a dedicated version-catalog entry pinned to the oldest supported material3 and use it only for sentry-compose's compileOnly, mirroring the existing androidx-compose-ui-replay entry (which already carries a "don't change without testing forwards compatibility" comment):

// sentry-compose/build.gradle.kts
compileOnly(libs.androidx.compose.material3.compat) // pinned to 1.2.1

Pinning libs.androidx.compose.material3 globally is not viable — the samples depend on newer material3 APIs and material icons.

Verified locally

Compiling sentry-compose with material3 pinned to 1.2.1:

  • :sentry-compose:compileReleaseKotlinAndroid succeeds
  • emitted bytecode reverts to rememberBoxMeasurePolicy, and shouldExecute / materializeModifier are gone from both affected classes
  • rememberBoxMeasurePolicy is present in foundation-layout 1.5.4 through 1.11.2, so it is both backward and forward compatible

Follow-up: add a regression guard

Nothing in CI asserts the supported Compose floor, which is why this shipped silently and went unnoticed for ~19 releases. We should add a guard so the next transitive bump can't reintroduce it — either a check that resolves the floor versions, or an assertion over the compiled bytecode for newer-than-floor internal symbols.

Open decision

Alternative: raise the documented floor to Compose 1.8.0 instead of restoring 1.6.3 compatibility. That is simpler, but is a breaking change for users on older Compose and needs a changelog entry and an explicit minimum-version statement.

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions