Thursday, May 27, 2010

How to fix: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.'

If you get this error in your code that uses Core Data, chances are you have a typo or are using wrong names for your entities when you're preparing your NSFetchRequest objects. That is, the names in your code (some of it which is autogenerated by Xcode) do not match the names in your model.

For instance, I was following some code snippets in the Pragmatic iPhone SDK book and I had somehow ended up with the following lines:


// Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];


Here the @"Event" name was wrong, as my .xcdatamodel file was actually using the name @"Track" for that entity. Changing that name in the code to match the model fixed the issue.

A similar naming mismatch was on this line:


NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];


The correct key for my model was @"name". There were other similar issues in the code.

One could argue that this is a shortcoming of the Xcode tool, as it fails to keep the names in the code generated by wizards in synch with changes in the model. As Core Data is a relatively new addition to the iPhone SDK, it's likely this will be improved in future versions.

4 comments:

Unknown said...

Thanks a bunch guy, I spent half a day on that one...
Kheldar

John Stewart said...

Ditto; was banging my head on this one. This post helped me out a bunch.

Kalim said...

Yeah,But if we need to caught that error,how will you do it without try catch block

Unknown said...

@Kalim - NSInvalidArgumentException, especially in this context, is a sign of a programming error. Such errors don't need to be caught, they need to be fixed in the source code.

Unlike other environments, like Java, where exceptions are also used to indicate events that may occur in the normal execution of the program (e.g. disk full, file not there, etc.), in Objective-C and Cocoa exceptions are usually thrown to indicate programming errors. That's why a failed NSAssert eventually throws an exception too. In a sense they're like unchecked exceptions in Java (http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html).