Didn't realize at first that something was wrong, because a) I wasn't very familiar with Coredata, just inherited the code to be upgraded and b) I created my own caching on top of CoreData to compensate some issues with CoreData. Then found this error buried deep into console logs:
CoreData Error Domain=NSCocoaErrorDomain Code=1570 "The operation couldn’t be completed. (Cocoa error 1570.)The debugging code which helped to discover the error code, while checking something else in app functionality - in other words my own cache was keeping app running regardless of CoreData failure. Now I know certain things should have been done in a different way...
NSError *error;You need to check incoming data and convert all missing values to some defaults. These defaults have to be either meaningful values or something that is later recognized as "empty" values e.g. NSNotFound or @"". Likewise your code needs to be able to handle these special cases gracefully. Yes, I did say gracefully and I do mean it.
if (![self.managedObjectContext save:&error])
Actually this crash happened when a mandatory entity relationship was nil, meaning that if it had been optional then nil might have been ok. However I should have added validation for all incoming data in any case.
Lesson learned: learn the tools that you need to use in a project, you will save time in the long run. Just beware that no customer wants to be the first one who has to invest the time for learning.
That's one of the reasons why I do hobby projects on my own time, to save customer time (FontType and Console On Device).