NSInvalidArgumentException - attempt to insert nil object from objects[0]

I get this error every time I try to save my Core Data viewContext (managedObjectContext). What does it mean? Is this a Swift 3 bug?


Actual SIGARBT Error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]


I've narrowed it down to a relationship object. I am doing a Fetch to obtain the object, which looks good, but when I save it the error indicates it is nil. Interestingly, the exact code works perfectly on one entity, but for the life of me I cannot see why it won't work for the other.


Sample Code - Fetch Object from Entity1:

  let fetchRequest: NSFetchRequest<Entity1> = Entity1.fetchRequest()
  fetchRequest.predicate = NSPredicate(format: "myRowNumber==%@", "101")     //Find a specific row
  let fetchResult: Entity1 = try self.viewContext.fetch(fetchRequest)[0]     //Grab result and cast it as Entity1
  print("THE FETCH RESULT LOOKS GOOD: \(fetchResult.value(forKey: "myRowNumber")!)")


Sample Code - Save to Entity2:

  let entity2 = NSEntityDescription.insertNewObject(forEntityName: "Entity2", into: self.viewContext) as! Entity2
  entity2.entity1 = fetchResult     //Set the relationship object from Fetch above
  entity2.text = "Some test text..."
  viewContext.save()     //Save the changes (try/catch removed) and that's when it crashes every time...

A Core Data save may potentially touch any object in your data model, so it's not necessarily the code you showed that causes the problem.


"[__NSPlaceholderArray initWithObjects:count:]" is the mechanism by which a new array is created from a C-style array of objects (presumably for reasons internal to the save), and the first object is nil.


One possible Swift-3-related cause is that objects now generally bridge to/from Any (instead of AnyObject), and that a Swift nil value can therefore get propagated into Obj-C code. So, my guess is that you've got code that is presented with a nil value, that isn't detecting it and is passing it through to CoreData.


I realize that's not much help, but it's something to think about. Note especially that where you have (say) an instance variable declared as type "SomeType!", and you assign it to a local variable ("let myThing = myInstanceVariable") the inferred type is now "SomeType?" where it used to be "SomeType!". This can cause bugs in code converted from Swift 2, since you're now propagating an optional unexpectedly.

I'm printing the contents of the Entity1 object before trying to save it to Entity2. All the properties are filled in except the one for the relationship between the to entities:


entity2_relationship = "<relationship fault: 0x6000002255a0 'entity2_relationship'>";


I set it to pull all of the properties instead of faults but it didn't help. I think Quincy has me looking in the right direction though.


fetchRequest.returnsObjectsAsFaults = false

Figured it out, and it only took three weeks!


First, here is the full entity layout:

Top, Entity1, Entity2, Entity3


Each of the above entities had a one-to-many relationship with the next. The problem was that the Fetch on Entity1 always had a FAULT for the "Top" relationship. Turns out that in the Model I had checked the box for "Arrangement: Ordered" on the relationship between Top and Entity1, and unchecking that box fixed it.


🙂

Thank you, this saved me a ton of time!

NSInvalidArgumentException - attempt to insert nil object from objects[0]
 
 
Q