MCRestrictionsPayload (allowListedAppBundleIDs) breaks Apple Watch native app enumeration — `nanotimekitcompaniond` reports "Missing .app from directory: /Watch/"

MCRestrictionsPayload (allowListedAppBundleIDs) breaks Apple Watch app enumeration — nanotimekitcompaniond reports "Missing .app from directory: <iOS-app>/Watch/"

Summary

Installing a Configuration Profile with com.apple.applicationaccess payload containing allowListedAppBundleIDs causes native Apple Watch apps to disappear from the paired Watch — even when their bundle IDs are explicitly in the whitelist. Log analysis shows this is not a bundle ID matching problem: nanotimekitcompaniond on the iPhone fails to enumerate the <companion>.app/Watch/ subdirectories where native watchOS app stubs live.

Follow-up to https://developer.apple.com/forums/thread/745585 — community-confirmed but received no official response.

Environment

  • iPhone 16 (iPhone17,3), iOS 26.4.2 (23E261), supervised
  • Apple Watch paired via Bridge.app
  • Profile installed locally via Apple Configurator (no MDM server required)

Smoking gun

Within ~5 seconds of profile install, two processes (nanotimekitcompaniond and NTKFaceSnapshotService) log identical errors for eight companion-app paths:

nanotimekitcompaniond[1498] <Error>: Missing .app from directory: file:///Applications/MobilePhone.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../Calculator.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../Bridge.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../MobileTimer.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../Camera.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../VoiceMemos.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../MobileMail.app/Watch/
nanotimekitcompaniond[1498] <Error>: Missing .app from directory: .../FindMy.app/Watch/
NTKFaceSnapshotService[3758] <Error>: Missing .app from directory: <same 8 paths>

The Watch's app icons and face complications both go through these processes, which explains the symptoms users see.

iOS itself flags the payload as Watch-incompatible — but applies it anyway

profiled[179] <Notice>: Payload class MCRestrictionsPayload (com.apple.applicationaccess) is not supported on any Watch version
profiled[179] <Notice>: Payload class MCRestrictionsPayload (com.apple.applicationaccess) is not available on HomePod
profiled[179] <Notice>: Beginning profile installation...
profiled[179] <Notice>: Profile "...v2..." installed.

So profiled knows the payload doesn't target watchOS — yet its side effects clearly manifest there.

Tests performed

TestBundle IDs in whitelistResult
v1249 (every installed iOS app: Apple + 3rd party)Walkie-Talkie, Messages, Find My + more disappear from Watch
v2295 (v1 + every Apple extension/Nano* daemon seen in syslog: *.MessagesActionExtension, *.FindMyNotifications*Extension, *.FindMyWidget*, com.apple.NanoBackup, com.apple.NanoMusicSync, com.apple.NanoPreferencesSync, com.apple.NanoTimeKit.face, com.apple.NanoUniverse.AegirProxyApp, com.apple.tursd, com.apple.FaceTime.FTConversationService, com.apple.Bridge.GreenfieldThumbnailExtension, etc.)Identical Missing-.app errors. Same apps disappear.

Conclusion: this is not a bundle ID matching issue — adding more IDs doesn't help. The system fails to enumerate <companion-iOS-app>.app/Watch/ regardless of whitelist contents. Many users in my prior thread reported trying 100+ bundle ID combinations without success; this evidence explains why.

Reproduction (no MDM required)

  1. Pair Apple Watch with iPhone normally.
  2. Generate a Configuration Profile with com.apple.applicationaccess + any non-empty allowListedAppBundleIDs array.
  3. Install via Apple Configurator's cfgutil install-profile, or AirDrop + Settings → Install.
  4. Within ~5 s, nanotimekitcompaniond errors appear (visible via idevicesyslog).
  5. Native Watch apps backed by an iOS companion stub disappear from the Watch's app grid and from face complications.

Hypothesis

MCRestrictionsPayload applies an enumeration filter that does not descend into .app/Watch/ subdirectories when computing visible apps. nanotimekitcompaniond consequently sees those directories as missing, the Watch's Carousel (SpringBoard equivalent) hides the apps, and NTKFaceSnapshotService can't load corresponding complications. Because profiled itself logs the payload as "not supported on any Watch version", this appears to be unintended bleed-through.

Questions for Apple

  1. Is MCRestrictionsPayload / allowListedAppBundleIDs officially supposed to affect Apple Watch apps? profiled says no.
  2. Is there an undocumented bundle ID pattern (e.g. <companion>.watchapp, or a Bridge.app/Watch/ prefix) that needs whitelisting to keep native Watch apps visible?
  3. Is the recommended workaround to use blacklistedAppBundleIDs instead?
  4. Should the enumeration error (Missing .app from directory: .../Watch/) be tracked as a separate watchOS framework bug?

Artifacts

Curated evidence log with timestamps, profile installer events, and the eight Missing-.app errors is attached as forum-post-v2-evidence.log. Full idevicesyslog captures (multiple install/remove cycles, ~2M log lines) and the .mobileconfig files are available on request.

Thanks — looking forward to guidance.

Answered by isach in 887670022

Update — root cause found and a working workaround

I cracked it. Posting the solution here so other admins can stop trying random bundle IDs.

Root cause (confirmed via watchOS sysdiagnose)

When you install a profile with com.apple.applicationaccess + allowListedAppBundleIDs, lsd on the paired Apple Watch immediately sends "uninstalledNotifications" for every PluginKit extension whose bundle ID is NOT in the whitelist. The watch's Carousel then cascades by terminating the parent apps that own those extensions, disguising the action as user initiated quit.

Captured from watchOS sysdiagnose at the moment of profile install:

17:22:56  lsd: Sending uninstalledNotifications for (
   pluginID=com.apple.MobileSMS.MessagesAssistantExtension
   pluginID=com.apple.tincan.SiriExtension
   pluginID=com.apple.SessionTrackerApp.SessionTrackerSiriExtension
)

17:23:13  Carousel: com.apple.MobileSMS:        terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.tincan:           terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.NanoNowPlaying:   terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.SessionTrackerApp:terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.HeartRate:        terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.DeepBreathing:    terminateApplication - uninstalling app (user initiated quit)

This is why adding more parent-app bundle IDs to the whitelist never helped — the whitelist filter is being applied at the PluginKit level, not the application level.

The workaround

You must whitelist the SiriKit extension bundle IDs of every Apple Watch native app, in addition to the parent bundle ID. Pattern:

com.apple.<app>                         # parent (likely already there)
com.apple.<app>.SiriExtension           # the missing piece
com.apple.<app>.*Extension              # any other PluginKit plugins the app ships

Confirmed critical extensions

For the three apps in my repro:

AppParent bundle IDRequired extension bundle ID
Walkie‑Talkiecom.apple.tincancom.apple.tincan.SiriExtension
Messagescom.apple.MobileSMScom.apple.MobileSMS.MessagesAssistantExtension
Workoutcom.apple.SessionTrackerAppcom.apple.SessionTrackerApp.SessionTrackerSiriExtension

Validation

Two independent install/remove cycles of a profile containing the above (308 bundle IDs total):

Cycle 1 (install v3): 0 Watch-side extensions in uninstalledNotifications. 
                      Walkie-Talkie, Messages, Find My all stayed visible.
Cycle 2 (remove v3 → reinstall v3): same result.

Before the fix, the same plugins were uninstalled on every profile install.

How to discover the extensions for your deployment

The extension bundle IDs can be enumerated directly from the watchOS sysdiagnose. Trigger a sysdiagnose, extract it, then:

# inside the extracted Watch sysdiagnose folder:
log show --info --debug --last 24h \
    --predicate 'eventMessage CONTAINS "pluginID="' \
    system_logs.logarchive \
    | grep -oE 'pluginID=com\.apple\.[a-zA-Z0-9._-]+' | sort -u

Whatever shows up that you care about — add to allowListedAppBundleIDs.

What is still a bug (Apple-side)

The fact that you have to whitelist watchOS-side extensions through an iOS payload that profiled itself logs as "not supported on any Watch version" is the underlying bug. The workaround above is just rerouting around it.

I will keep the FB open and update the OP if Apple responds. For now: shipping this so others stop chasing the parent bundle IDs.

Environment: iPhone 16 / iOS 26.4.2 (23E261), Apple Watch on watchOS 6.3.1 (build 17U208), supervised iPhone, profile installed locally via Apple Configurator (no MDM server needed to reproduce).

Accepted Answer

Update — root cause found and a working workaround

I cracked it. Posting the solution here so other admins can stop trying random bundle IDs.

Root cause (confirmed via watchOS sysdiagnose)

When you install a profile with com.apple.applicationaccess + allowListedAppBundleIDs, lsd on the paired Apple Watch immediately sends "uninstalledNotifications" for every PluginKit extension whose bundle ID is NOT in the whitelist. The watch's Carousel then cascades by terminating the parent apps that own those extensions, disguising the action as user initiated quit.

Captured from watchOS sysdiagnose at the moment of profile install:

17:22:56  lsd: Sending uninstalledNotifications for (
   pluginID=com.apple.MobileSMS.MessagesAssistantExtension
   pluginID=com.apple.tincan.SiriExtension
   pluginID=com.apple.SessionTrackerApp.SessionTrackerSiriExtension
)

17:23:13  Carousel: com.apple.MobileSMS:        terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.tincan:           terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.NanoNowPlaying:   terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.SessionTrackerApp:terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.HeartRate:        terminateApplication - uninstalling app (user initiated quit)
17:23:13  Carousel: com.apple.DeepBreathing:    terminateApplication - uninstalling app (user initiated quit)

This is why adding more parent-app bundle IDs to the whitelist never helped — the whitelist filter is being applied at the PluginKit level, not the application level.

The workaround

You must whitelist the SiriKit extension bundle IDs of every Apple Watch native app, in addition to the parent bundle ID. Pattern:

com.apple.<app>                         # parent (likely already there)
com.apple.<app>.SiriExtension           # the missing piece
com.apple.<app>.*Extension              # any other PluginKit plugins the app ships

Confirmed critical extensions

For the three apps in my repro:

AppParent bundle IDRequired extension bundle ID
Walkie‑Talkiecom.apple.tincancom.apple.tincan.SiriExtension
Messagescom.apple.MobileSMScom.apple.MobileSMS.MessagesAssistantExtension
Workoutcom.apple.SessionTrackerAppcom.apple.SessionTrackerApp.SessionTrackerSiriExtension

Validation

Two independent install/remove cycles of a profile containing the above (308 bundle IDs total):

Cycle 1 (install v3): 0 Watch-side extensions in uninstalledNotifications. 
                      Walkie-Talkie, Messages, Find My all stayed visible.
Cycle 2 (remove v3 → reinstall v3): same result.

Before the fix, the same plugins were uninstalled on every profile install.

How to discover the extensions for your deployment

The extension bundle IDs can be enumerated directly from the watchOS sysdiagnose. Trigger a sysdiagnose, extract it, then:

# inside the extracted Watch sysdiagnose folder:
log show --info --debug --last 24h \
    --predicate 'eventMessage CONTAINS "pluginID="' \
    system_logs.logarchive \
    | grep -oE 'pluginID=com\.apple\.[a-zA-Z0-9._-]+' | sort -u

Whatever shows up that you care about — add to allowListedAppBundleIDs.

What is still a bug (Apple-side)

The fact that you have to whitelist watchOS-side extensions through an iOS payload that profiled itself logs as "not supported on any Watch version" is the underlying bug. The workaround above is just rerouting around it.

I will keep the FB open and update the OP if Apple responds. For now: shipping this so others stop chasing the parent bundle IDs.

Environment: iPhone 16 / iOS 26.4.2 (23E261), Apple Watch on watchOS 6.3.1 (build 17U208), supervised iPhone, profile installed locally via Apple Configurator (no MDM server needed to reproduce).

MCRestrictionsPayload (allowListedAppBundleIDs) breaks Apple Watch native app enumeration — &#96;nanotimekitcompaniond&#96; reports "Missing .app from directory: /Watch/"
 
 
Q