Observation
The /pairings RemovePairing handler (pairings.go, DeletePairing branch) looks up the target pairing and, when it isn't found, responds with an error:
p, err := srv.st.Pairing(d.Identifier)
if err != nil {
log.Info.Println(err) // e.g. open <store>/<id>.pairing: no such file or directory
tlv8Error(res, M2, TlvErrorUnknown)
return
}
Expected (per Apple's reference implementation)
Apple's HomeKitADK, HAPPairingPairingsRemovePairingGetM2:
If a pairing for RemovedControllerPairingIdentifier does not exist, the accessory must return success.
It skips removal and returns M2 success — no error.
Source: https://github.com/apple/HomeKitADK/blob/master/HAP/HAPPairingPairings.c
Impact (suspected, not yet confirmed)
On a real home, iOS periodically issues RemovePairing to clean up a stale controller (e.g. a resident hub whose pairing it wants dropped). Because the accessory returns an error for an already-absent pairing, iOS appears never to consider the cleanup complete and retries indefinitely — observed as a recurring loop:
pair-verify.go: not paired with <id> yet
pairings.go: open <store>/<id>.pairing: no such file or directory
The light otherwise pairs and works; this is residual noise + a controller that never fully reconciles.
Proposed fix
In the not-found case, return M2 success instead of TlvErrorUnknown (match the ADK).
Status
Observation
The
/pairingsRemovePairinghandler (pairings.go, DeletePairing branch) looks up the target pairing and, when it isn't found, responds with an error:Expected (per Apple's reference implementation)
Apple's HomeKitADK,
HAPPairingPairingsRemovePairingGetM2:It skips removal and returns M2 success — no error.
Source: https://github.com/apple/HomeKitADK/blob/master/HAP/HAPPairingPairings.c
Impact (suspected, not yet confirmed)
On a real home, iOS periodically issues RemovePairing to clean up a stale controller (e.g. a resident hub whose pairing it wants dropped). Because the accessory returns an error for an already-absent pairing, iOS appears never to consider the cleanup complete and retries indefinitely — observed as a recurring loop:
The light otherwise pairs and works; this is residual noise + a controller that never fully reconciles.
Proposed fix
In the not-found case, return M2 success instead of
TlvErrorUnknown(match the ADK).Status