How to Fix Fastlane Build Failures With gym and xcodebuild

When build_app (gym) fails, the real cause is usually a wrong scheme, an archive error, or a Ruby and Xcode version mismatch. Here is how to diagnose and fix each.

How build_app Actually Works

The build_app action, historically called gym, is a wrapper around Apple's xcodebuild. It archives your app and exports a signed .ipa using the export options you provide.

Because it wraps xcodebuild, most build_app failures are really xcodebuild failures surfaced through Fastlane. That is good news: the underlying error is almost always visible if you read the full log.

Understanding this relationship reframes debugging.

You are not fighting Fastlane; you are fixing an xcodebuild or configuration problem that Fastlane faithfully reported. That distinction points you toward the right logs and settings instead of the wrong tool.

It also means most of what you learn about fixing build_app failures is really knowledge about xcodebuild and Xcode project configuration. That knowledge transfers directly whether you run builds through Fastlane, a CI script, or Xcode itself.

It is worth noting that build_app has two distinct phases: archiving and exporting. Keeping those phases separate in your mind is the single most useful habit for debugging, because a failure in one phase points at a very different set of causes than a failure in the other.

Step 1: Find the Real Error in the Log

Fastlane prints a concise summary at the end, but the actionable detail is higher up in the xcodebuild output. Scroll up to find the first genuine error, not the final failing status.

Build logs are verbose. Look for lines marked as errors, often near a compilation failure, a missing file, or a signing message. That first error is usually the root cause; everything after it is fallout.

If the log is overwhelming, try reproducing the same build with xcodebuild directly or by opening the project in Xcode.

If it fails there too, the problem is in your project, not Fastlane, and you can debug it with Xcode's richer tooling.

Step 2: Confirm the Scheme and Project Are Correct

A very common failure is Fastlane pointing at the wrong scheme, workspace, or project. If build_app cannot find the scheme, or builds the wrong one, it fails or produces unexpected results.

Check that the scheme name you pass exactly matches a shared scheme in your project. Schemes must be marked as shared in Xcode to be visible to command-line tools; an unshared scheme is invisible to xcodebuild.

If you use CocoaPods or Swift packages that produce a workspace, ensure build_app targets the .xcworkspace, not the bare .xcodeproj.

Pointing at the wrong container is a frequent cause of missing-dependency errors that look like code problems but are really configuration problems.

Step 3: Resolve Dependency and Clean-Build Issues

Builds that pass locally but fail on CI often stem from dependencies. If you use CocoaPods, ensure pod install runs before build_app. For Swift Package Manager, ensure packages resolve, which may require network access on the runner.

Stale derived data can also cause phantom failures. A clean build, which build_app can perform, sometimes clears errors caused by leftover artifacts from a previous run.

On CI specifically, remember the runner starts fresh.

Anything your local machine has cached, from pods to resolved packages, must be reproduced in the pipeline, or the build will fail in ways you never see locally.

Committing your dependency lockfiles helps here. A committed Podfile.lock or Package.resolved lets the runner resolve the exact same dependency versions you built against, which removes a subtle source of local-versus-CI divergence.

Step 4: Fix Export and Signing Configuration

If the archive succeeds but export fails, the export options are usually wrong. The export method must match your intent, such as app-store for TestFlight and App Store builds, and it must be consistent with the provisioning profile in use.

A mismatch between the export method and the available signing assets produces export failures even when compilation was fine. Confirm Match fetched the matching distribution profile and that build_app is told to use it.

Isolate the two phases mentally.

If compilation passes but export fails, focus entirely on signing and export options rather than your source code, since the code already compiled successfully.

The export options plist that build_app generates or accepts is where the export method and signing style are recorded. When export fails, inspecting those options against the profile Match provided usually reveals the mismatch immediately.

Step 5: Address Ruby and Bundler Problems

Fastlane is a Ruby tool, and Ruby environment issues cause a distinct class of failures that look like build failures but are really setup failures. Symptoms include gem version conflicts, Bundler errors, or Fastlane refusing to start.

Manage Fastlane through a Gemfile and run commands with bundle exec so the version is pinned. Commit both the Gemfile and Gemfile.lock so CI installs exactly what you use locally.

If CI uses a different Ruby version than your machine, behavior can diverge.

Pin the Ruby version in your CI configuration to match local development and eliminate this variable entirely.

Step 6: Handle Xcode Version Mismatches

Builds are sensitive to the Xcode version. A project that builds on your local Xcode may fail on a CI runner with a different Xcode installed, sometimes due to deprecated settings or new build requirements.

On CI, explicitly select the Xcode version your project targets rather than relying on the runner default. Many CI providers offer a way to pin Xcode, and Fastlane can help select it.

When Apple ships a new Xcode, expect occasional build changes.

Test releases against the specific Xcode version you intend to ship with, and upgrade deliberately rather than being surprised by a runner's default changing underneath you.

Step 7: Build a Reproducible Pipeline

The through-line for reliable builds is reproducibility. Pin your Fastlane version with Bundler, pin your Ruby version, and pin your Xcode version on CI. Most mysterious build failures trace back to one of these drifting.

Run a clean build lane locally before pushing pipeline changes, and keep dependency resolution steps explicit in your lanes rather than assuming cached state.

When a build does fail, resist changing many things at once.

Read the first real error, fix that specific issue, and re-run. Signing, scheme, dependencies, and version pinning cover the overwhelming majority of build_app failures.

Changing one thing at a time also gives you a clear cause-and-effect trail. When a single fix turns the build green, you know exactly what was wrong and can document it, so the next occurrence is a quick lookup rather than a fresh investigation.

Frequently Asked Questions

Why does build_app say my scheme cannot be found?

Most often the scheme is not marked as shared in Xcode, so command-line tools cannot see it, or the name passed to build_app does not exactly match. Share the scheme and verify the exact name.

My build works in Xcode but fails in Fastlane, why?

Common causes are pointing at the wrong project or workspace, missing dependency installation like pod install on CI, or a different Xcode or Ruby version. Reproduce the exact environment to isolate it.

The archive succeeds but export fails. What is wrong?

The export options usually do not match your signing setup. Ensure the export method matches your intent, such as app-store, and that the matching provisioning profile is available, typically via Match.

Do I need to pin my Ruby and Xcode versions?

Yes, for reliable CI. Pinning Fastlane via Bundler, plus the Ruby and Xcode versions, eliminates a large class of failures caused by environment drift between local and CI.