the watch wasn't broken. my iphone was behind.
this is the sequel to my apple watch paired fine. then it forgot., where i ended with "the fault is on the watch" and "this needs a watchos fix". it didn't. what fixed it was updating the iphone. this writeup is how i checked that, because i couldn't prove it the way i wanted to, and what the evidence does and doesn't say.
tl;dr
- the watch was on watchos 27.2 the whole time. the iphone was on ios 27.0. updating only the watch (what i tried first) kept it newer than its companion.
- unpairing and re-pairing the watch in the watch app, still on ios 27.0, didn't help. device hub kept failing with
DeviceKitError 4002. - updating the iphone to ios 27.2 and pairing from device hub worked. the iphone's analytics logs line up: the update finished at 00:26, after the re-pairing, with no further re-pairing after it.
- i can't see the coredevice side anymore, so the cause is a hypothesis (version mismatch), not a diagnosis. fb24924229 is still open.
the symptom that was left
after re-pairing, device hub's live view of the watch kept failing:
DeviceKitError errorCode 4002
"Live device view took longer than expected to connect."
the iphone ↔ watch link was healthy (mirroring worked). only the mac ↔ watch path through device hub was dead, which is the same shape as the original bug. nothing i tried on the mac changed it.
where i went looking
i wanted the pairing logs from the night i re-paired. the mac's unified log had nothing:
$ log show --last 24h --predicate 'process == "remotepairingd"' | wc -l
0
those messages expire within hours. but the iphone keeps its own record, and it's much longer-lived: it keeps .ips diagnostic files for weeks (settings ▸ privacy & security ▸ analytics & improvements ▸ analytics data), and devicectl can copy them without any extra tool:
$ xcrun devicectl device info files --device <iphone> --domain-type systemCrashLogs
$ xcrun devicectl device copy from --device <iphone> --domain-type systemCrashLogs \
--source <file> --destination <path>
480 files, going back to at least the 27th of september. two of them mattered, and one trick: the header of every JetsamEvent-*.ips records the os build at that moment, so a pile of crash-ish files becomes a version history.
the timeline
local time, utc−6, all read from the iphone:
| when | what the files show |
|---|---|
| until oct 2, 17:19 | iphone on ios 27.0 (24A5418b) |
| oct 2, 22:06 → 22:41 | the watch's pairing identity on the iphone changes: one ProxiedDevice-* folder stops, another starts |
| oct 2, 23:45 – 23:54 | a pairing performance report: activation ~11 s, passcode and unlock pairing, initial sync, no errors |
| oct 3, 00:26 | iphone updated to ios 27.2 (24B5089g); ota_result_success |
| from oct 3, 10:27 | iphone on 27.2; the same watch identity until the end of the files, no further re-pairing |
the watch was on watchos 27.2 (24S5091f) under both identities. so for the whole failure the watch was newer than its iphone.
after the update, devicectl device info details on the watch reads pairingState: paired, transportType: localNetwork, authenticationType: manualPairing, and installing apps on it worked again.
what this proves and what it doesn't
- it proves the mismatch existed (27.2 watch, 27.0 iphone), that the iphone ↔ watch pairing was clean, and that the improvement came with the iphone update, not with another re-pairing.
- it doesn't prove why.
remotepairingdandverifyManualPairingnever land in these files, so the reason the watch asked for a brand-new pair-setup in a loop is still unexplained. "the companion and the watch must run matching versions" is my working hypothesis. i'd say it out loud as a hypothesis. - it can't tell me one detail: the identity switch is logged at 22:41 and the pairing report spans 23:45–23:54. either i made more than one attempt that night, or the report is written at the end. the files don't say.
mistakes i made along the way
- updating only the watch. it looked like the obvious thing ("retested on watchos 27.2: same behavior") and it widened the gap with the iphone.
- writing "the fault is on the watch" with the iphone still on a different build. every control i ran compared the watch against the iphone, and never asked whether their versions matched. the first thing to check on a companion device is the companion's version.
- looking for the evidence in the one log that expires. the mac's log had nothing; the iphone's kept it for weeks.
takeaways
- check that companions match before debugging the protocol. iphone and watch on the same release line. a minute of work that i did last.
- analytics logs are a version history. every jetsam header carries the os build, and
devicectl ... systemCrashLogsgets them off the phone. - capture before you pair. if it happens again:
log stream --predicate 'process == "remotepairingd" OR process == "CoreDeviceService"'into a file, then pair. - a fix isn't a diagnosis. this one worked, and i still don't know the mechanism.
links
- docs/resolution.md: the timeline above, the commands and the limits, in english and español
- the original investigation
- kisnner26/watchos27-pairing-bug