expo / expo/eas-cli

iOS build fails at INSTALL_PODS with `spawn pod ENOENT` on macOS Tahoe 26 / Xcode 26.6 image — CocoaPods installed in prior phase but not on PATH

Open
#4,214 0 comments 0 reactions 0 assignees View on GitHub
needs review
Dominant language
TypeScript
Stars
1.4k
Forks
236
Avg merge
3d 1h
Merged PRs (30d)
91

Description

### Build/Submit details page URL

https://expo.dev/accounts/icetea168/projects/iqnition/builds/807e5d0f-0c80-44e6-a36d-ab7ef070ff87

### Summary

## Summary

EAS Build iOS jobs on the current `latest` image (macOS Tahoe 26.5.2, Xcode 26.6, Apple M4 Pro) fail immediately at the `INSTALL_PODS` phase with `spawn pod ENOENT`. CocoaPods **does** install successfully during the earlier `INSTALL_CUSTOM_TOOLS` phase (version 1.16.2, pinned via `eas.json`), but the `pod` binary is not on PATH when `INSTALL_PODS` executes ~22ms later.

Pinning `"cocoapods": "1.16.2"` in `eas.json` confirms the install succeeds — but PATH isn't inherited into the next phase's shell.

## Environment

- **eas-cli:** 20.3.0 (also reproduced installing @latest = 22.0.0)
- **Expo SDK:** 54.0.36
- **Runtime version:** 1.2.1
- **EAS image:** whatever `latest` resolves to today — reports as macOS Tahoe 26.5.2 / Xcode 26.6 (17F113) / Apple M4 Pro / 5 vCPUs / 20 GB RAM
- **Profile config (relevant excerpt):**
```json
"production": {
"ios": {
"buildConfiguration": "Release",
"image": "latest",
"cocoapods": "1.16.2"
}
}

Steps to reproduce

1. eas build -p ios --profile production --non-interactive on any Expo SDK 54 project with a bundled iOS surface
2. Watch INSTALL_CUSTOM_TOOLS phase log: CocoaPods 1.16.2 installed successfully
3. Watch INSTALL_PODS phase (starts ~22ms later): fails immediately with spawn pod ENOENT

Full log excerpt from failed build:
INSTALL_PODS phase START at 2026-08-15T19:36:05.677Z

"Detected expo=54.0.36; not enabling precompiled modules use because
precompiled modules require expo>=55.0.26."

[ERROR] "spawn pod ENOENT"
Error: spawn pod ENOENT
at ChildProcess._handle.onexit (node:internal/child_process:285:19)
at onErrorNT (node:internal/child_process:483:16)
at process.processTicksAndRejections (node:internal/process/task_queues:89:21)

INSTALL_PODS phase FAILED at 2026-08-15T19:36:05.700Z (duration: 22ms)

Expected

pod binary installed in INSTALL_CUSTOM_TOOLS should be on PATH in the subsequent INSTALL_PODS phase.

Actual

ENOENT — PATH from the gem install isn't inherited into the next phase's shell.

Reference

- Failing build ID: 807e5d0f-0c80-44e6-a36d-ab7ef070ff87 (project 509602f3-c05c-49cb-aad6-4ee3e4ce266a)
- Previous successful build on same repo (2026-08-14): 3629afcd-3825-4a17-85c6-8ef999b8809a — was on prior default image (pre-Tahoe/26.6 rollout)

Impact

Blocks all iOS production builds on latest image. Suspect this affects everyone on that image tonight, not just this project. Workaround (pinning to an older image identifier) is being attempted.

### Managed or bare?

Managed — no ios/ or android/ directories in the repo; prebuild happens on EAS (visible in your build logs as "Read app config" → "Install dependencies" → "Prebuild" flow). Your app.json has a plugins array (expo-router, expo-video, @sentry/react-native, expo-iap, etc.) — that's the managed-with-config-plugins pattern.

### Environment

npx expo-env-info

That'll produce something like:

expo-env-info 1.x.x environment info:
System:
OS: macOS 26.5.2
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.x.x
Yarn: 1.x.x
npm: 10.x.x
Utilities:
Xcode: 26.6/17F113
CocoaPods:
npmPackages:
expo: 54.0.36
react-native: 0.76.x
...
npmGlobalPackages:
eas-cli: 20.3.0

The Xcode/CocoaPods lines are the important ones for this bug (confirms your local ↔ EAS toolchain mismatch context isn't the cause; the bug is EAS-side).

### Error output

_No response_

### Reproducible demo or steps to reproduce from a blank project

This is an EAS infra issue (their macOS image PATH is broken), not an SDK code bug — Snack can't demonstrate infra failures. Give them minimal fresh-project steps instead. Paste this:

This is a platform-side issue in the EAS macOS Tahoe 26 / Xcode 26.6 build image — it reproduces on ANY managed Expo project that has native modules requiring `pod install`. A Snack won't help (Snack doesn't run EAS builds). Minimal repro from a blank project:

```bash
# 1. Fresh managed Expo project
npx create-expo-app@latest tahoe-pod-repro --template blank
cd tahoe-pod-repro

# 2. Add any native module that requires a pod (any one of these will do)
npx expo install expo-secure-store

# 3. Configure EAS
npm i -g eas-cli
eas init
eas build:configure

# 4. Add a production ios profile to eas.json:
{
"cli": { "version": ">= 18.0.0", "requireCommit": false },
"build": {
"production": {
"channel": "production",
"ios": {
"buildConfiguration": "Release",
"image": "latest",
"cocoapods": "1.16.2"
}
}
}
}
# 5. Kick the build
eas build -p ios --profile production --non-interactive

Observe: INSTALL_CUSTOM_TOOLS phase reports CocoaPods 1.16.2 installed. INSTALL_PODS phase 22ms later fails immediately with spawn pod ENOENT. Build errors before compile.

Not needed to reproduce:
- Any specific SDK version (54.0.36 in my case, but the failure is in the shell environment between phases, not the JS)
- Any project code changes
- expo-iap or any specific pod — any native module with a pod triggers it

Root cause hypothesis: the shell that runs INSTALL_PODS is spawned without inheriting the PATH augmentations from INSTALL_CUSTOM_TOOLS. The gem-installed pod binary lives at (probably) /usr/local/lib/ruby/gems/3.x.x/bin/pod or similar and that directory isn't on PATH for the next phase.

Workaround: pin to an older image value that predates the Tahoe 26 rollout (attempting macos-sequoia-15.4-xcode-16.3 currently — will report back if invalid).

The point of that framing: **you're not asking them to debug your project, you're telling them their image is broken** and giving them a minimal way to reproduce it on any project of their choosing (including their own internal test rigs). That's the shortest path to their team accepting the bug and fixing the image.

Contributor guide

Open the contributing guide

Research direction

Start by locating the EAS build-phase implementations for INSTALL_CUSTOM_TOOLS and INSTALL_PODS, then reproduce the failure with the minimal create-expo-app and eas build steps in the issue. Compare the PATH used by both phases; done means CocoaPods installed in the first phase is resolvable by the second and the managed iOS build proceeds past INSTALL_PODS.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, macos, ruby, typescript
Domain
ci-cd, infrastructure, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.