Description
When a user's iCloud storage is full, saving parent records in CloudKit fails with quotaExceeded. SyncEngine ignores this, and that record is never sent again. The record is kept locally on device however.
Later, when a child that references that parent record is sent later, CloudKit rejects it this time with referenceViolation, rather than quotaExceeded. handleSentRecordZoneChanges treats all referenceViolation errors as the parent being deleted from another device, and with the child's ON DELETE CASCADE, that child is deleted from the local database.
Checklist
Expected behavior
When iCloud storage is full, records are still saved locally, and uploaded again once storage is available
Actual behavior
Children of a parent that was never uploaded to CloudKit are deleted because of referenceViolation when they are sent later to CloudKit. We observed this behavior in our app and we were able to consistently reproduce it with an iCloud account that had no free storage left. Turning off iCloud made child record persist locally
Reproducing project
https://github.com/jalalawqati/ReferenceViolationReproduce
SQLiteData version information
1.12.0
Sharing version information
2.10.1
GRDB version information
7.11.1
Destination operating system
iOS 26.6
Xcode version information
Xcode 26.6
Swift Compiler version information
swift-driver version: 1.148.6 Apple Swift version 6.3.3 (swiftlang-6.3.3.1.1 clang-2100.1.1.101)
Target: arm64-apple-macosx26.0
Description
When a user's iCloud storage is full, saving parent records in CloudKit fails with
quotaExceeded.SyncEngineignores this, and that record is never sent again. The record is kept locally on device however.Later, when a child that references that parent record is sent later, CloudKit rejects it this time with
referenceViolation, rather thanquotaExceeded.handleSentRecordZoneChangestreats allreferenceViolationerrors as the parent being deleted from another device, and with the child'sON DELETE CASCADE, that child is deleted from the local database.Checklist
mainbranch of this package.Expected behavior
When iCloud storage is full, records are still saved locally, and uploaded again once storage is available
Actual behavior
Children of a parent that was never uploaded to CloudKit are deleted because of
referenceViolationwhen they are sent later to CloudKit. We observed this behavior in our app and we were able to consistently reproduce it with an iCloud account that had no free storage left. Turning off iCloud made child record persist locallyReproducing project
https://github.com/jalalawqati/ReferenceViolationReproduce
SQLiteData version information
1.12.0
Sharing version information
2.10.1
GRDB version information
7.11.1
Destination operating system
iOS 26.6
Xcode version information
Xcode 26.6
Swift Compiler version information