Skip to content

sentry.gradle.kts still breaks Gradle Configuration Cache on 8.19.0 / Gradle 9 — a small, targeted fix is possible ahead of the SAGP migration (#796) #6466

Closed

Description

@fabiendem

What React Native libraries do you use?

Hermes, RN New Architecture, React Native without Frameworks

Are you using sentry.io or on-premise?

sentry.io (SaS)

Are you using any other error monitoring solution alongside Sentry?

Yes

Other Error Monitoring Solution Name

Datadog (@datadog/mobile-react-native) and Luciq (@luciq/react-native). Noted because both ship Gradle scripts with the same Configuration Cache incompatibility — this report is scoped to Sentry's.

@sentry/react-native SDK Version

8.19.0 (latest). Confirmed via a Configuration Cache build failure on 8.10.0; the code responsible is present verbatim in 8.19.0's sentry.gradle.kts (line references below), so it applies to latest — I have inspected the source but not re-run a build on 8.19.0.

How does your development environment look like?

Gradle: 9.0.0 (Configuration Cache is the recommended execution mode; Gradle prints this on every build)
AGP: 8.x
React Native: 0.83.9, Hermes enabled, newArchEnabled=true
Build: ./gradlew :app:bundleRelease (release AAB; observed on Linux CI, ubuntu-24.04)

Sentry.init()

Sentry.init({
  dsn: 'https://...@sentry.io/...',
  // standard options; the failure is at build time, independent of runtime init options
});

Steps to Reproduce

  1. Set org.gradle.configuration-cache=true in android/gradle.properties
  2. Set org.gradle.configuration-cache.problems=warn (to get past warn-level problems and surface the hard failures)
  3. ./gradlew :app:bundleRelease (or any release bundle/assemble)

Expected Result

The build succeeds with Configuration Cache enabled (stores an entry on the first run, reuses it — and skips the configuration phase — on subsequent runs).

Actual Result

problems=warn does not rescue these — they are hard execution-time exceptions (this is also what #4252 reported, with warn mode set):

* What went wrong:
Could not evaluate onlyIf predicate for task
  ':app:createBundleReleaseJsAndAssets_SentryUpload_<pkg>@<version>+<code>'.
> Could not evaluate spec for 'Task satisfies onlyIf closure'.

The same failure also occurs for :app:copySentryJsonConfiguration.


Root cause

Line references are to packages/core/sentry.gradle.kts on main (shipped in 8.19.0); the Groovy sentry.gradle in 8.10.0 has the identical constructs.

1. onlyIf predicates call closures resolved from project's extra properties, and are evaluated at execution time.

// sentry.gradle.kts
fun shouldCopySentryOptionsFile(): Boolean {
    val closure = extra["shouldCopySentryOptionsFile"] as groovy.lang.Closure<*>   // L87 — reads project state
    return closure.call() as Boolean
}

tasks.register("copySentryJsonConfiguration") {                                     // L103 (unconditional)
    onlyIf { shouldCopySentryOptionsFile() }                                        // L104 — evaluated at execution time → project access
    ...
}

Also onlyIf { shouldCopySentryOptionsFile() } at L159 and onlyIf { shouldSentryAutoUploadGeneral() } at L561 (the *_SentryUpload task). onlyIf runs at execution time; resolving the extra-property closure there is the CC violation.

2. copySentryJsonConfiguration's doLast touches project at execution time.

doLast {
    val appRoot = project.rootDir.parentFile ?: project.rootDir   // L106 — project at execution time
    ...
    copy { from(sentryOptionsFile); into(androidAssetsDir); ... }  // L113 — project.copy at execution time
}

3. *_SentryUpload uses project.logger at execution time (e.g. L594, L596, and elsewhere in its actions). The CLI invocation itself already uses the CC-safe injected ExecOperations (InjectedExecOps, defined L76, instantiated L577) — so only these residual project accesses remain.

Why the usual escape hatches don't work

  • Upgrading to the 8.14.0+ .kts rewrite (#6119) does not help — verified by reading sentry.gradle.kts on main: it is a syntax migration, the CC-relevant constructs above are unchanged.
  • Env-var gating (SENTRY_DISABLE_AUTO_UPLOAD=true, SENTRY_COPY_OPTIONS_FILE=false) does not help: copySentryJsonConfiguration is registered unconditionally (L103) and wired unconditionally via preBuild.dependsOn("copySentryJsonConfiguration") in afterEvaluate (L781–782), so it is always in the task graph and its onlyIf is always evaluated. The env var only changes the predicate's result, not whether the failing evaluation runs.

Proposed minimal fix (interim, ahead of #796)

All CC-safe patterns, no behaviour change:

  1. onlyIf (L104, L159, L561) — capture the env read at configuration time and reference the captured boolean:

    val copyOptionsFile   = System.getenv("SENTRY_COPY_OPTIONS_FILE") != "false"
    val autoUploadGeneral = System.getenv("SENTRY_DISABLE_AUTO_UPLOAD") != "true"
    // ...
    onlyIf { copyOptionsFile }
    onlyIf { autoUploadGeneral }

    (System.getenv at configuration time is a tracked CC input.)

  2. project.rootDir (L106) — capture at configuration time and use the local in doLast.

  3. copy {} (L113) — use an injected FileSystemOperations (same injection pattern already used for ExecOperations), or java.nio.file.Files.copy for the single-file case.

  4. project.logger (L594/L596/actions) — use the task's own logger instead of project.logger (the task logger is CC-safe).

I'm happy to open a PR with these changes as an interim step before the full SAGP migration in #796 — let me know if you'd prefer to fold it directly into that work instead.

References

Activity

  1. linear-code commented on Jul 17, 2026

    @linear-code
  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jul 17, 2026
  3. sentry-pierre commented on Jul 17, 2026

    @sentry-pierre

    I inspected packages/core/sentry.gradle.kts and your analysis is spot-on. All three CC violations are present exactly where you say they are:

    • onlyIf { shouldCopySentryOptionsFile() } and onlyIf { shouldSentryAutoUploadGeneral() } resolve closures from project.extra at execution time.
    • copySentryJsonConfiguration's doLast reads project.rootDir and calls project.copy.
    • The _SentryUpload task actions use project.logger inside both doFirst and doLast.

    Your proposed interim fix is sound. Since the SAGP migration (#796) has slipped, a small targeted PR here is the pragmatic path — please go ahead if you're still willing.

  4. fabiendem commented on Jul 17, 2026

    @fabiendem
    ContributorAuthor

    Opened a PR with the interim fix: #6469.

    It removes the execution-time project access from copySentryJsonConfiguration and the *_SentryUpload tasks (the onlyIf predicates, project.rootDir, project.copy, project.logger, Project.file), which is what produced the hard Could not evaluate onlyIf predicate failure under org.gradle.configuration-cache=true.

    Verified end-to-end on a React Native 0.83.9 app with Gradle 9.0.0 (against the equivalent Groovy sentry.gradle shipped in 8.x, ported 1:1 to the .kts):

    • Before: Could not evaluate onlyIf predicate for task ':app:copySentryJsonConfiguration' → BUILD FAILED
    • After: > Task :app:copySentryJsonConfiguration runs → BUILD SUCCESSFUL

    A review pass also caught a behavior regression in the first revision (capturing SENTRY_DISABLE_AUTO_UPLOAD at apply-time bypassed the Expo disableAutoUpload override that reassigns project.ext.shouldSentryAutoUploadGeneral after apply from); the PR now captures the overridable closures inside the onVariants callback so that override is honored.

    One warn-level Configuration Cache problem remains and is intentionally out of scope of that PR: resolveSentryReactNativeSDKPath runs node --print require.resolve(...) as a config-time external process — the same pattern several other RN libraries use, which doesn't fail the build. Left for a follow-up so the PR stays focused on the hard failures, ahead of the full SAGP migration (getsentry/sentry-android-gradle-plugin#796).

  5. alwx commented on Jul 20, 2026

    @alwx
    Contributor

    Hey @fabiendem and thanks for reporting!
    We'll review both your issue and the PR shortly and follow up if we need more information or once next steps are clearer.

  6. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jul 20, 2026
  7. self-assigned this
    on Jul 20, 2026
  8. github-actions commented on Jul 23, 2026

    @github-actions
    Contributor

    A PR closing this issue has just been released 🚀

    This issue was referenced by PR #6469, which was included in the 8.20.0 release.

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

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions