Summary
The warning CoreData: error: This store file was previously used on a build with Persistence-1523 but is now running on a build with Persistence-1522 indicates a metadata version mismatch between the Core Data framework (which SwiftData wraps) used to create the store and the one currently attempting to open it. Despite the error, the store opens successfully because backward compatibility is generally preserved. The root cause is usually an environment mismatch: the store was created by a newer version of the OS or SDK than the one running on the target device or simulator.
Root Cause
Core Data assigns a Persistence ID to the store file. This ID changes when the underlying SQL schema or Core Data stack implementation changes in a new SDK or OS release.
- Environment Divergence: The “source” database was likely created or touched by a version of the Core Data framework (e.g., iOS 17 / Xcode 15) different from the environment where the app is currently running (e.g., iOS 16 / Xcode 14).
- Mismatches occur in two directions:
- New Store → Old Runtime: If the store was created with a newer Persistence ID (e.g., 1523) and you try to open it on an older OS version (expecting 1522), the warning triggers.
- Old Store → New Runtime: The reverse triggers a “Migration” warning, which is expected.
- Validation Logic: Core Data checks the
NSStoreTypeVersionKeyin the store’s metadata against the framework’s currentNSPersistentStoreCoordinatorversion capabilities. A mismatch triggers the error log, but if the schema is compatible, the open operation succeeds.
Why This Happens in Real Systems
- Developer Toolchains: A developer might build the “Mac editing app” using a beta SDK or a newer Xcode version than the one used for the iOS app target. If the Mac app creates or modifies the store file, it stamps it with the newer Persistence ID.
- Simulator vs. Device: The simulator often runs a different (often newer) OS version than the physical device being targeted for testing, leading to ID mismatches when copying stores between them.
- App Thinning: When shipping a pre-seeded database, the file is static. If that file was generated on a machine with a newer SDK than the minimum deployment target, the mismatch is baked into the binary asset.
Real-World Impact
- Log Noise: The primary impact is verbose and confusing log output, making it difficult to spot genuine runtime errors.
- Potential Migration Loops: In rare cases, if the underlying model versions are actually incompatible, this warning precedes a crash or failure to load data.
- App Store Review: While usually harmless, unexplained errors can sometimes draw unnecessary scrutiny during app review if logs are heavily analyzed.
- Developer Confusion: Junior engineers often misinterpret this as a corruption warning and waste time regenerating databases or rebuilding models unnecessarily.
Example or Code
// No specific code snippet is required to fix the metadata issue,
// but here is how one might inspect the store metadata if diagnosing this programmatically:
import Foundation
import CoreData
do {
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: URL(fileURLWithPath: "path/to/source.store"))
if let version = metadata["NSStoreModelVersionHashes"] {
print("Model Version Hash: \(version)")
}
} catch {
print("Error reading metadata: \(error)")
}
How Senior Engineers Fix It
The solution is standardization, not technical workaround.
- Standardize the Build Environment: Ensure the Mac utility used to edit the database and the iOS app project use the exact same Xcode version and SDK.
- Regenerate the Store: Open the empty store in the Mac app built with the target iOS SDK version, let it initialize, and then fill it with data. This ensures the metadata matches the target environment exactly.
- Ignore if Deployed: If the app is already in production and users aren’t experiencing crashes, the senior engineer’s decision is usually to suppress the log or simply accept it, as it indicates a valid forward-compatibility path. Updating the SDK used to generate the seed data prevents future occurrences.
Why Juniors Miss It
- Misunderstanding “Persistence”: Juniors often confuse “Persistence” number errors with “Persistent History Tracking” or data corruption.
- Over-reliance on SQLite Tools: They might assume
VACUUMorPRAGMAcommands fix metadata, but these operate on the SQL level, not the Core Data wrapper metadata. - Fear of Data Loss: The word “error” in the console triggers an immediate desire to fix the data, whereas the warning is actually about the tooling version, not the data integrity.