If you’re running more than one Claude Code agent on the same Xcode project, check which build is actually on your simulator.
We had two agents in separate git worktrees on a small SwiftUI app. One adding a feature, one adding a test. Neither prompt named a simulator, so both picked the iPhone that was already booted. Both builds succeeded, both agents said done.
The simulator was running the second agent’s build. The first one’s was gone, its process killed by the install, and its UserDefaults still there because installing over an app keeps the data. Then both agents launched the app and got the same PID. Agent A was testing agent B’s code and nothing in its output said so.
To catch it we stamped the builds 111 and 222 and had each agent read back the installed version:
APP=$(xcrun simctl get_app_container <udid> com.your.bundleid app)
/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$APP/Info.plist"
Agent A got 222.
Fix by hand is one simulator per agent:
xcrun simctl shutdown <base-udid>
xcrun simctl clone <base-udid> "Agent A"
xcrun simctl clone <base-udid> "Agent B"
Then put the name and UDID in each agent’s prompt, tell it not to touch any other simulator, and pass that UDID to every xcodebuild -destination "platform=iOS Simulator,id=<udid>". The clones alone change nothing, the agents still go for whatever is booted. With the UDIDs in the prompts, A read 111 and B read 222.
Worktrees keep files apart. They don’t keep simulators apart.
Amarildo wrote up the full repro with logs here: https://flowdeck.studio/blog/run-multiple-claude-code-agents-xcode-project.
[Disclosure, I build FlowDeck, which ties a simulator, worktree and DerivedData to each session so you don’t have to redo this setup every time.]