Core Data crash when used in widget extension

I have this very simple PersistenceController setup. It's used in both the main app and widget target.

struct PersistenceController {
    static let shared = PersistenceController()
    
    @MainActor
    static let preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        return result
    }()
    
    let container: NSPersistentContainer
    
    /// The main context.
    var context: NSManagedObjectContext {
        return container.viewContext
    }
    
    init(inMemory: Bool = false) {
        container = NSPersistentContainer(name: "Gamery")
        
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        } else {
            do {
                let storeURL = try URL.storeURL(forAppGroup: "XXXXXXXXXX", databaseName: "Gamery")
                let storeDescription = NSPersistentStoreDescription(url: storeURL)
                
                /// Enable history tracking for cloud syncing purposes.
                storeDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)

                print("### Persistent container location: \(storeURL)")
                
                container.persistentStoreDescriptions = [storeDescription]
            } catch {
                print("Failed to retrieve store URL for app group: \(error)")
            }
        }
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                Crashlytics.crashlytics().record(error: error)
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        
        container.viewContext.automaticallyMergesChangesFromParent = true
        container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
        
        #if !WIDGET
        if !inMemory {
            do {
                try container.viewContext.setQueryGenerationFrom(.current)
            } catch {
                fatalError("###\(#function): Failed to pin viewContext to the current generation: \(error)")
            }
        }
        
        PersistentHistoryToken.loadToken()
        #endif
    }
}

I regularly receive crash logs from the widget. I never experienced crashes myself and the widgets work fine.

GameryWidgetExtension/PersistenceController.swift:35: 
Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=256 "The file “Gamery.sqlite” couldn’t be opened." 
UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/B6A63FE1-ADDC-4A4C-A065-163507E991C6/Gamery.sqlite, NSSQLiteErrorDomain=23}, 
["NSSQLiteErrorDomain": 23, "NSFilePath": /private/var/mobile/Containers/Shared/AppGroup/B6A63FE1-ADDC-4A4C-A065-163507E991C6/Gamery.sqlite]

I have absolutely no idea what's going on here. Anyone who can help with this?

I'd start with pointing you to this thread, which addressed a similar issue – A widget failed to open a shared Core Data store sometimes.

The root cause in that case was that the backup process removed the -wal file (after merging it to the main database), which led to the failure when the widget tried to load the store with read-only mode (NSReadOnlyPersistentStoreOption).

Your code snippet doesn't show that you load the store with the mode, and so that is probably not your case. However, rather than throwing an error, Core Data will simply create a new (empty) store when it loads a store normally (as shown in your code snippet) and the store URL doesn't exist. Now that you got the error, I am wondering if you have other code path that does the same thing as the mentioned thread.

If that's a bad guess, I'd consider capturing a sysdiagnose, finding the error message in the system log, and then checking if there is any hint around there. Typically, Core Data / SQLite logs more information to the system log, which hopefully unveils the reason of the failure, as it did in the mentioned case.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Core Data crash when used in widget extension
 
 
Q