iOS on-demand runtime downloads never actually free disk space (mobileassetd cache outlives simctl runtime delete)

Open Beginner friendly
#79 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Documentation
Clarity
Mostly clear
Activity status
Active
Tech stack
ios, macos, typescript

Research direction

Read src/drivers/ios/index.ts to understand the existing disk-preflight wording, then review docs/CONFIGURATION.md and docs/known-pitfalls.md. Document that on-demand iOS simulator downloads can remain in the macOS mobileassetd cache after simctl deletion, and explain the operator-facing cleanup path described in the issue; done means the caveat is clear without proposing unsafe automated deletion.

Written by the indexing model from the issue text.

Description

bug:ready

What happened

While doing real-device E2E verification of #69 (on-demand component installation) I downloaded several iOS simulator runtimes via simlock lease --allow-download / directly via xcodebuild -downloadPlatform iOS, then cleaned up between test runs with xcrun simctl runtime delete <id> (and later ... delete all).

simctl runtime delete only unregisters the runtime from CoreSimulator's active list. It does not evict the underlying download from macOS's own mobileassetd cache at /System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime/. Every distinct build downloaded during the session (including ones where the foreground xcodebuild process was killed/timed-out, which does not stop the background mobileassetd transfer) left behind a ~7.5-8GB .asset bundle there.

By the end of one afternoon of testing this left 8 asset bundles (~63GB) on disk, and xcrun simctl list runtimes kept resurfacing "already installed" runtimes I had deleted minutes earlier (apparently CoreSimulatorService opportunistically re-registers/re-mounts whatever is still sitting in the mobileassetd cache, e.g. after a CoreSimulatorService restart or simctl runtime scan-and-mount). Free disk space on the test machine dropped from 62GB to ~1GB.

Why this matters for Simlock

  • downloads policy and the IOS_RUNTIME_MIN_FREE_BYTES disk preflight in the iOS driver (src/drivers/ios/index.ts) check free disk space before a download, which is the right check for a single request — but they have no visibility into (and can't reclaim) this OS-level cache. An operator running Simlock with downloads.policy: "always" (or even "on-request" with agents frequently requesting different --os pins) on a long-lived host can accumulate many GB of mobileassetd cache over time that never gets reclaimed by anything Simlock does, silently eating into the same disk budget the preflight is trying to protect.
  • This is not something simctl runtime delete (which is presumably what an operator would reach for, and is the only iOS-side cleanup Simlock's own docs could plausibly recommend) fixes -- verified directly: deleting the registered runtime, even via the all alias, did not shrink /System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime.
  • The only reliable fix found so far is Xcode's own Settings -> Platforms pane (trash icon per platform), or manually removing the .asset bundles under /System/Library/AssetsV2/... as root -- neither of which Simlock can safely automate today (the latter is real system-directory surgery outside anything the daemon should be doing unsupervised).

Suggested follow-up (not scoped/decided yet)

  • At minimum, document this caveat somewhere operator-facing (docs/CONFIGURATION.md / docs/known-pitfalls.md) -- "on-demand iOS downloads accumulate an OS-level cache that Simlock cannot reclaim; on a long-lived host with downloads.policy enabled, expect to periodically reclaim this manually via Xcode's Platforms settings."
  • Possibly worth a simlock doctor finding if disk pressure is observed alongside a large mobileassetd iOS-simulator cache, pointing the operator at the fix, since the existing disk-pressure/preflight machinery has no way to distinguish "genuinely full disk" from "full because of a reclaimable OS cache."
  • No obvious safe automated remediation within Simlock's own process (no supported public API to evict a mobileassetd cache entry that isn't currently registered as an installed runtime) -- flagging for awareness/docs rather than proposing a driver code change.

Repro

  1. simlock lease --platform ios --device "iPhone 16 Pro" --os <version not installed> --allow-download --detach
  2. xcrun simctl runtime delete all (or delete the specific runtime id)
  3. du -sh /System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime -- unchanged
  4. Repeat with a few different --os values -- cache grows, unbounded, with nothing in Simlock or simctl able to reclaim it short of Xcode's GUI or manual root cleanup.

macOS 26.6.1, Xcode 27.0 (27A5228h).

Dominant language
TypeScript
Stars
14
Forks
0
Avg merge
22h 33m
Merged PRs (30d)
60

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from callstackincubator/simlock

All issues in callstackincubator/simlock

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.