You bump the SDK, tidy a few dependencies, and send an Android build to EAS. The log turns red at the bottom and stops here.
FAILURE: Build failed with an exception.
* Where:
Script '/home/expo/workingdir/build/node_modules/@sentry/react-native/sentry.gradle' line: 127
> Could not find method exec() for arguments [...] on task ':app:createBundleReleaseJsAndAssets_SentryUpload_...' of type org.gradle.api.DefaultTask.You haven't touched your own build.gradle, and yet something is "not found". It's the kind of moment where my hands stop moving.
What I'd like to say first: the line worth reading is not the final error, it's the Script '…' line: N two lines above it. It names the package and the line number outright.
This message matches the one reported in expo/expo issue #42494 (during the SDK 55 preview, filed in January 2026, now closed). As far as that page goes, it happened with @sentry/react-native 7.2.0 and Sentry fixed it in 7.3.0. The page doesn't explain the mechanism; the title only offers "Gradle 9 incompatibility" as the reading. What I verified myself is the log-parsing part below. I did not reproduce the EAS build itself, so please read it with that in mind.
Why the script line, not your app code
Gradle error text is long on task names and short on meaning. The Script '…' line: line, by contrast, tells you which file was executing when things fell over. If that path points into node_modules/, the cause is an installed package (and its version), not your app.
Gradle 9 also dropped the project-level exec() call that had been deprecated for a while, so an old-style script failing on a newer Gradle is the skeleton of this message. That's my understanding from the migration notes, not something I confirmed on a specific log. So before deciding "Gradle got newer", I collect facts in this order:
- Pull the package name out of the failing script path
- Look at the version actually installed
- Check whether the same symptom was reported and which version fixed it
- Raise the version and rebuild with the same dependency set
Steps 1 and 2: a small script to extract the package
Reading logs by eye gets tiring, so I wrote this. Save the log from the EAS page and pass it in; it prints the package, script, line, and symptom.
#!/usr/bin/env bash
# Usage: bash who-called-gradle.sh build.log
# Extract which node_modules script failed, and on which line, from a Gradle log
log="${1:?pass a log file}"
line=$(grep -m1 "^Script '" "$log") || { echo "No Script line found (the failure may be in your own build.gradle)"; exit 1; }
path=$(printf '%s' "$line" | sed -E "s/^Script '([^']+)'.*/\1/")
lno=$(printf '%s' "$line" | sed -E "s/.*line: ([0-9]+).*/\1/")
pkg=$(printf '%s' "$path" | sed -E 's#.*/node_modules/((@[^/]+/)?[^/]+)/.*#\1#')
echo "package : $pkg"
echo "script : ${path##*/node_modules/}"
echo "line : $lno"
grep -m1 -oE "Could not find method [a-zA-Z]+\(\)" "$log" | sed 's/^/symptom : /'
echo "next : npm ls $pkg # check the installed version"Run against a sample log shaped like the one above (sample-eas.log), it printed:
package : @sentry/react-native
script : @sentry/react-native/sentry.gradle
line : 127
symptom : Could not find method exec()
next : npm ls @sentry/react-native # check the installed versionGiven a file with no Script line (I tried one containing just plain error), it says the failure may be in your own build.gradle and exits with code 1. I added that branch because the thing I most wanted to avoid was a script that prints nothing and looks like it succeeded.
The sample log is my own reconstruction from the issue text. If your real EAS log differs in line numbers or surrounding output, adjust the grep patterns to match.
Step 3: has this been reported, and which version fixed it?
Once you have the package name, search that repository's issues, or Expo's. In this case the fix was reported in @sentry/react-native 7.3.0, so an installed 7.2.0 is a match.
One caution: the version Expo recommends (what npx expo install pulls in) and the version the package fixed things in can disagree. The reporter pointed out that Expo's own recommended version was the affected 7.2.0. "I installed it with expo install, so it's fine" doesn't always hold.
# Which version is installed (and is it only a transitive dependency?)
npm ls @sentry/react-native
# Show drift from what Expo expects
npx expo install --checkThe second command lists mismatched packages and offers to fix them. Before accepting, I save the output so I can read back what changed.
Step 4: raise the version and send the same build again
Once you know the fixed version, install it explicitly.
npx expo install @sentry/react-native@7.3.0 # example: the first version with the fix
npx expo-doctor # did the mismatches grow?
eas build --platform android --profile productionI pinned 7.3.0 because the issue named it as the first fixed version. Jumping to the latest is an option, but it can move the mismatch somewhere else. I'd rather confirm the build passes on the smallest fix first, and treat "should I go further" as a separate decision.
What I still don't know
As an indie developer who ships Android release builds by hand, I often have to move forward with gaps like these. Three things are unverified in this write-up.
| Not verified | Why |
|---|---|
| That I reproduced the same error on EAS | I didn't. Only the log-parsing script was run, against a sample log |
| Which Gradle 9 change is the direct cause | The issue page doesn't explain the mechanism; I'm quoting the title's reading |
| Whether other Gradle scripts keep the same old style | I only looked at Sentry |
The third one nags at me. If it happened with Sentry, other packages may still carry the same old call and simply haven't been stepped on yet. After each SDK bump, a quick grep -rn "exec(" node_modules --include=*.gradle might let you notice before a production build does.
Where I draw the line
With build failures, fixing the last red line tends to be the longer way around.
Read the line that says where it fell, not the line that says what it felt. Versions only enter the conversation once that line has pointed at a package.
As a first step, if you still have a recent failed log, run it through the script once. If a package name comes out, half the work is done.
For how dependency versions drift without anyone noticing, I also wrote up a count of how far Expo's bundled modules slide across patch releases.
Sources: