NSManagedObject of class 'className' must have a valid NSEntityDescription error
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The error "An NSManagedObject of class 'ClassName' must have a valid NSEntityDescription" is one of the most common Core Data crashes in iOS and macOS development. It occurs when Core Data cannot find an entity description matching your managed object subclass. This typically happens due to a mismatch between the class name in code, the entity name in the .xcdatamodeld file, or the module/namespace configuration.
What Causes This Error
Core Data uses NSEntityDescription to map entity names in the data model to Swift/Objective-C classes. When you create or fetch a managed object, Core Data looks up the entity by class name. If the lookup fails, you get this crash.
The most common causes:
- Module name mismatch — The entity's class in the data model inspector does not include the correct module prefix
- Entity not in the data model — The entity was deleted or renamed in
.xcdatamodeldbut the class still exists - Wrong managed object context — Using a context whose persistent store coordinator loads a different data model
- Codegen conflict — Xcode's automatic code generation conflicts with manually created subclass files
Fix 1: Set the Correct Module in the Data Model
This is the most common fix. In Xcode:
- Open your
.xcdatamodeldfile - Select the entity
- In the Data Model Inspector (right panel), check the Class section:
- Name: Should match your Swift class name (e.g.,
Person) - Module: Set to Current Product Module (not blank, not a specific module name)
If the module field is blank or set to a wrong module, Core Data cannot find your class. For Swift, the full class name includes the module (e.g., MyApp.Person), and setting "Current Product Module" tells Core Data to use the app's module automatically.
Fix 2: Verify Entity and Class Names Match
The entity name in your data model and the class registered with Core Data must match:
The @objc(Person) attribute is critical — without it, Swift mangles the class name (e.g., MyApp.Person), and Core Data may not find it.
Fix 3: Check Codegen Settings
Xcode can automatically generate NSManagedObject subclasses. Conflicts arise when you also have manual subclass files:
- Select your entity in
.xcdatamodeld - In the Data Model Inspector, check Codegen:
- Class Definition: Xcode generates the full class. Do NOT create manual subclass files.
- Category/Extension: Xcode generates properties as an extension. You create the class manually.
- Manual/None: You manage everything manually.
Clean Build After Changing Codegen
After changing codegen settings:
- Product → Clean Build Folder (Shift+Cmd+K)
- Delete the app from the simulator
- Delete the DerivedData folder:
~/Library/Developer/Xcode/DerivedData/ - Rebuild
Fix 4: Register the Managed Object Model Correctly
Ensure the persistent container loads the correct data model:
Manual Model Loading
Fix 5: Creating Objects Correctly
Always create managed objects through the context, not with init():
Fix 6: Unit Testing Configuration
This error frequently appears in unit tests because the test target has a different module:
Common Pitfalls
- Forgetting
@objc(ClassName): Without this attribute, Swift uses the fully qualified name (e.g.,MyApp.Person), which does not match the entity namePersonin the data model. Always add@objc(EntityName)to your managed object subclasses. - Module set to "Global namespace": In the Data Model Inspector, leaving the Module field blank defaults to the global namespace. For Swift classes, set it to "Current Product Module."
- Stale DerivedData: After changing entity names, codegen settings, or module configuration, Xcode may cache old generated files. Always clean DerivedData after model changes.
- Multiple data models: If your app has multiple
.xcdatamodeldfiles, ensure you load the correct one. Creating an object whose entity lives in a different model than the context's coordinator will trigger this error. - Migration issues: After renaming an entity, lightweight migration may fail if the mapping is not configured. Use a mapping model or
NSEntityMigrationPolicyfor entity renames.
Summary
- Set the entity's Module to "Current Product Module" in the Data Model Inspector
- Add
@objc(EntityName)to your managed object subclass for correct Objective-C name exposure - Match the entity name in
.xcdatamodeldexactly with the class name in code - Resolve codegen conflicts: use either Xcode-generated or manual subclass files, not both
- Always create managed objects via
Person(context:)orNSEntityDescription.insertNewObject, never bareinit() - Clean DerivedData and rebuild after any data model configuration changes

