March 9, 2020 · Swift

Core Data Errors

If you're trying to use Core Data in your project, especially if you're testing, you might find some obscure errors. Here are a few and how to fix them:

Multiple Entity Descriptions:

+[BlogEngine.Account entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass[error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'BlogEngine.Account' so +entity is unable to disambiguate.

This happens when you have more than one NSPersistentStoreContainer working in an app. In your app, it might be because different parts of the app are trying to spin up their own Core Data stacks rather than passing that information between them. This is an architecture problem.

In tests this can more easily happen. Some of your tests may need to create a Core Data stack. This also needs to be shared, especially if you enable parallel testing (which you should, it's good for speeding up your tests and uncovering concurrency bugs). I fixed this issue in my own tests by introducing a single container configured for in-memory storage that all test cases can access.

Even if your tests all use the same container, if your tests are using your app for a test host, you will see the same error again. This is because the your app has it's own container open at the same time as your tests.

Desired Type and Given Type

    - Unacceptable type of value for to-one relationship: property = "account"; desired type = BlogEngine.Account; given type = BlogEngine.Account; (followed by crash logs)

Especially if you are using Swift for your Core Data code, the compiler helps to make sure you're using the right types, right? Except the error there says the expected type as BlogEngine.Account, but also the given type was BlogEngine.Account. They look the same, that shouldn't be an issue. This can be because of the same issue as above. An Account from one container and an Account from another container are different, even if they have the same name. Make sure you are using Core Data objects from the same context and same stack when assigning relationships.

Now go forth and use Core Data for good!