Skip to content

Isolate DerivedData per workspace to avoid conflicts with concurrent sessions #340

Description

@codeman9

When multiple MCP sessions (or CLI invocations) build the same project from different clones, they all share a single flat ~/Library/Developer/XcodeBuildMCP/DerivedData directory. Because xcodebuild only creates hashed per-project subdirectories when using its default DerivedData location — not when an explicit -derivedDataPath is passed — concurrent builds of the same project collide on the shared Build/, SourcePackages/, etc.

This causes corrupted incremental builds, race conditions, and unpredictable failures when running parallel agent sessions against separate clones of the same repo.

Proposed solution: Hash the workspace/project root path into the DerivedData subdirectory, e.g.:

~/Library/Developer/XcodeBuildMCP/DerivedData/<scheme>-<hash-of-workspace-root>/

This mirrors how Xcode isolates DerivedData per workspace in its default location. The hash should be derived from the resolved absolute path of the workspace or project file so that different clones get different directories automatically.

Current workaround: Set a unique XCODEBUILDMCP_DERIVED_DATA_PATH env var or derivedDataPath session default per session.

Activity

  1. added a commit that references this issue on Apr 15, 2026
    a720f17
  2. ihuseynoff commented on Apr 17, 2026

    @ihuseynoff

    I've also faced the same issues.
    Workaround that's working for me (multiple Claude Code sessions, one per git worktree):

    Set derivedDataPath to a relative path inside each worktree root via session_set_defaults:

    derivedDataPath: .build/DerivedData
    

    Because each worktree is a separate directory, .build/DerivedData resolves to a unique absolute path per session automatically — no manual hashing or env var coordination needed. .build/ is gitignored so it doesn't pollute the repo.

    Bonus issue I hit on top of this: When an MCP tool call is cancelled mid-run, the child xcodebuild process orphans and keeps the DerivedData + simulator lock. A subsequent build/test call then hangs waiting for that lock. I mitigated it with a Claude Code PreToolUse hook that sweeps orphaned xcodebuild processes rooted under our project's .build/DerivedData before each new tool call.

  3. added a commit that references this issue on Apr 20, 2026
    0f2418a
  4. added 5 commits that reference this issue on Apr 28, 2026
    79f9c42
    f65ce9b
    cbf0305
    bced024
    6a593f9
  5. added a commit that references this issue on Apr 28, 2026
    9600359
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions