Description
withSentryIOS (Expo config plugin, @sentry/react-native 7.2.0) writes two Xcode build phases whose command substitutions are unquoted, so any project living in a path with a space fails to build (/bin/sh: /Users/me/My: No such file or directory):
-
plugin/src/withSentryIOS.ts — "Bundle React Native code and images" rewrite:
(match) => `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`
SENTRY_REACT_NATIVE_XCODE_PATH is a backtick command substitution that expands to an absolute path; unquoted, it word-splits. Same for the react-native-xcode.sh invocation kept from the template.
-
Same file — "Upload Debug Symbols to Sentry" phase:
shellScript: `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`,
-
scripts/sentry-xcode.sh — the SENTRY_DISABLE_AUTO_UPLOAD=true branch re-parses its argument unquoted:
/bin/sh -c "$REACT_NATIVE_XCODE"
(the upload-enabled branch already re-quotes via REACT_NATIVE_XCODE_WITH_SENTRY — only the disable branch is broken)
Reproduction (no Xcode needed)
The defect is pure shell parsing:
$ export PODS_TARGET_SRCROOT="/tmp/My App/node_modules/x/ios"
$ sh -c 'echo /bin/sh `echo "$PODS_TARGET_SRCROOT/../scripts/f.sh"`'
/bin/sh /tmp/My App/node_modules/x/ios/../scripts/f.sh
Three words after expansion → at execution time /bin/sh receives /tmp/My as its script. End-to-end: put any Expo app using the Sentry plugin in a directory whose path contains a space, npx expo prebuild -p ios, then build — the "Bundle React Native code and images" phase fails with /bin/sh: <first-path-segment>: No such file or directory.
Fix (verified on a real app in a spaced path — full Release build green with these applied via patch-package)
--- a/plugin/src/withSentryIOS.ts
+++ b/plugin/src/withSentryIOS.ts
@@
- shellScript: `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`,
+ shellScript: `/bin/sh "${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}"`,
@@
- return script.replace(/^.*?(packager|scripts)\/react-native-xcode\.sh\s*(\\'\\\\")?/m,
- (match) => `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_PATH} ${match}`);
+ return script.replace(/^.*?(packager|scripts)\/react-native-xcode\.sh.*$/m,
+ (match) => `/bin/sh "${SENTRY_REACT_NATIVE_XCODE_PATH}" "${match}"`);
--- a/scripts/sentry-xcode.sh
+++ b/scripts/sentry-xcode.sh
@@
- /bin/sh -c "$REACT_NATIVE_XCODE"
+ /bin/sh -c "\"$REACT_NATIVE_XCODE\""
Note on the regex change: with the Expo bare template, the old regex stops at react-native-xcode.sh, leaving the substitution's trailing '" + backtick outside the match — so wrapping only ${match} in quotes would produce an unbalanced line. Matching to end-of-line keeps the full backtick expression inside the added quotes. Quoted command substitutions ("…") are valid as command words and collapse to a single argument.
Related: expo/expo has the same class of bug in the expo-constants / expo-updates podspecs and in the bare template's bundle phase — reported in expo/expo#48705.
SDK version
- @sentry/react-native 7.2.0 (Expo plugin), Expo SDK 54, react-native 0.81.5, Xcode 26.6, macOS 26.3.1
Description
withSentryIOS(Expo config plugin,@sentry/react-native7.2.0) writes two Xcode build phases whose command substitutions are unquoted, so any project living in a path with a space fails to build (/bin/sh: /Users/me/My: No such file or directory):plugin/src/withSentryIOS.ts— "Bundle React Native code and images" rewrite:SENTRY_REACT_NATIVE_XCODE_PATHis a backtick command substitution that expands to an absolute path; unquoted, it word-splits. Same for thereact-native-xcode.shinvocation kept from the template.Same file — "Upload Debug Symbols to Sentry" phase:
scripts/sentry-xcode.sh— theSENTRY_DISABLE_AUTO_UPLOAD=truebranch re-parses its argument unquoted:/bin/sh -c "$REACT_NATIVE_XCODE"(the upload-enabled branch already re-quotes via
REACT_NATIVE_XCODE_WITH_SENTRY— only the disable branch is broken)Reproduction (no Xcode needed)
The defect is pure shell parsing:
Three words after expansion → at execution time
/bin/shreceives/tmp/Myas its script. End-to-end: put any Expo app using the Sentry plugin in a directory whose path contains a space,npx expo prebuild -p ios, then build — the "Bundle React Native code and images" phase fails with/bin/sh: <first-path-segment>: No such file or directory.Fix (verified on a real app in a spaced path — full Release build green with these applied via patch-package)
Note on the regex change: with the Expo bare template, the old regex stops at
react-native-xcode.sh, leaving the substitution's trailing'"+ backtick outside the match — so wrapping only${match}in quotes would produce an unbalanced line. Matching to end-of-line keeps the full backtick expression inside the added quotes. Quoted command substitutions ("…") are valid as command words and collapse to a single argument.Related: expo/expo has the same class of bug in the
expo-constants/expo-updatespodspecs and in the bare template's bundle phase — reported in expo/expo#48705.SDK version