Skip to content

Runner app crashes on iOS Simulator with Xcode 26.4 — _Testing_Foundation.framework not found #3003

@cdeil

Description

@cdeil

I upgraded to Xcode 26.4 today and Patrol started to crash like this:

Image

The crash report at https://gist.github.com/cdeil/7513c99991be66d93d33b7e316e1a5f5 does show this:

Process:             Runner [83564]
Path:                /Users/USER/Library/Developer/CoreSimulator/Devices/AF113FB9-9946-4379-A8CB-C154569BFF3A/data/Containers/Bundle/Application/E650F580-944C-4136-B654-E1FEF3336DFB/Runner.app/Runner
...
Termination Reason:  Namespace DYLD, Code 1, Library missing
Library not loaded: @rpath/_Testing_Foundation.framework/_Testing_Foundation
...

I asked my coding agent to identify the issue and it claims to have found the root cause - see below.

It did run experiments to reproduce the crash a few times and I think also successfully fixed it ( see below ). I didn't open a PR because I don't know if patching the path is even the right direction.

Can anyone from the maintainers reproduce with Xcode 26.4?

Summary

On Xcode 26.4 (and likely 26.2+), running patrol tests on the iOS Simulator causes
the Runner app (app under test) to crash at launch with:

Termination Reason: Namespace DYLD, Code 1, Library missing
Library not loaded: @rpath/_Testing_Foundation.framework/_Testing_Foundation
Referenced from: Runner.app/Frameworks/libXCTestSwiftSupport.dylib

The test runner (RunnerUITests-Runner) starts fine — it's the app-under-test
(Runner.app) that crashes because it can't find _Testing_Foundation.framework.

This could be the same issue or related to #2981,
which was closed as not-reproducible. We can reproduce it reliably and have identified
the root cause and a fix.

Environment

  • macOS: 26.4
  • Xcode: 26.4 (Build 17E38)
  • Flutter: 3.41.4 (stable)
  • Patrol CLI: 4.3.0
  • Patrol package: 4.5.0
  • Simulator: iPhone 17 Pro Max (iOS 26.4)

Root Cause

When xcodebuild build-for-testing generates the .xctestrun file, it sets
DYLD_FRAMEWORK_PATH differently for the test runner vs the app under test:

TestingEnvironmentVariables (test runner) — ✅ Correct

__TESTROOT__/Debug-iphonesimulator
:__TESTROOT__/Debug-iphonesimulator/PackageFrameworks
:__PLATFORMS__/iPhoneSimulator.platform/Developer/Library/Frameworks  ← has this

UITargetAppEnvironmentVariables (app under test) — ❌ Missing

__TESTROOT__/Debug-iphonesimulator
:__TESTROOT__/Debug-iphonesimulator/PackageFrameworks
                                                                     ← missing!

The _Testing_Foundation.framework (new in Xcode 26.x) lives at:

/Applications/Xcode.app/Contents/Developer/Platforms/
  iPhoneSimulator.platform/Developer/Library/Frameworks/_Testing_Foundation.framework

This path resolves via __PLATFORMS__/iPhoneSimulator.platform/Developer/Library/Frameworks.

The app under test embeds libXCTestSwiftSupport.dylib which dynamically links
_Testing_Foundation.framework via @rpath. Without the platform frameworks
directory in DYLD_FRAMEWORK_PATH, dyld can't find it and the app crashes
before Patrol even connects.

Reproduction Steps

  1. Use Xcode 26.4 on macOS
  2. Create any Flutter app with patrol tests
  3. Run patrol test -t <test> --device "iPhone 17 Pro Max"
  4. Observe: test runner starts, app crashes, test hangs then fails with
    "Early unexpected exit, operation never finished bootstrapping"

Verify the bug manually

# After patrol build ios --simulator, inspect the xctestrun:
XCTESTRUN=$(ls build/ios_integ/Build/Products/*.xctestrun | head -1)

# This has __PLATFORMS__ (correct):
/usr/libexec/PlistBuddy -c \
  "Print :RunnerUITests:TestingEnvironmentVariables:DYLD_FRAMEWORK_PATH" \
  "$XCTESTRUN"

# This is MISSING __PLATFORMS__ (bug):
/usr/libexec/PlistBuddy -c \
  "Print :RunnerUITests:UITargetAppEnvironmentVariables:DYLD_FRAMEWORK_PATH" \
  "$XCTESTRUN"

Fix

The fix patches the xctestrun file after xcodebuild build-for-testing completes,
adding the missing __PLATFORMS__ framework path to UITargetAppEnvironmentVariables.

See the diff in packages/patrol_cli/lib/src/ios/ios_test_backend.dart in #3005

What the fix does

  1. After xcodebuild build-for-testing succeeds (in build() method)
  2. Reads UITargetAppEnvironmentVariables.DYLD_FRAMEWORK_PATH from the xctestrun
  3. If __PLATFORMS__ is missing, appends
    __PLATFORMS__/iPhoneSimulator.platform/Developer/Library/Frameworks
  4. Writes the updated value back using /usr/libexec/PlistBuddy

The fix is idempotent (checks before patching) and only applies to simulator builds.

Manual workaround (without the code fix)

XCTESTRUN=$(ls build/ios_integ/Build/Products/*.xctestrun | head -1)
/usr/libexec/PlistBuddy -c \
  "Set :RunnerUITests:UITargetAppEnvironmentVariables:DYLD_FRAMEWORK_PATH \
  __TESTROOT__/Debug-iphonesimulator:\
  __TESTROOT__/Debug-iphonesimulator/PackageFrameworks:\
  __PLATFORMS__/iPhoneSimulator.platform/Developer/Library/Frameworks" \
  "$XCTESTRUN"

Then run patrol test --no-build ... or xcodebuild test-without-building ....

Notes

  • This may also be a Flutter bug (Flutter's xcode_backend.sh generates the Xcode
    project) or an Xcode bug (xcodebuild should be consistent between
    TestingEnvironmentVariables and UITargetAppEnvironmentVariables).
  • The fix in patrol_cli is the right place because patrol controls the build pipeline
    and can patch before executing tests, regardless of where the root cause lies upstream.
  • The fix is safe for older Xcode versions — if __PLATFORMS__ is already present,
    it's a no-op.

Metadata

Metadata

Assignees

Labels

P0Critical issues such as a build break or regressionpackage: patrol_cliRelated to the patrol_cli packageplatform: iosiOS is affected

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions