SwiftData: Inserting two entities with same relationship target crashes

I have a Model Class Note:

@Model
class Note {
    var id: UUID
    var created: Date
    var content: String
    
    @Relationship(inverse: \Event.notes)
    var events:  [Event]?
    
    init(_ content: String, created: Date = .now, events: [Event] = []) {
        self.id = UUID()
        self.created = created
        self.content = content
        self.events = events
    }
}

And Event:

@Model
class Event: Hashable, Equatable {
    var id: String
    var name: String
    var eventNotes: String?
    @Relationship var notes: [Note]?
    
    // @Transient does not publish (iOS bug?), use .ephemeral instead
    @Attribute(.ephemeral) var isSelected: Bool = false
    
    init(_ name: String = "Unnamed Event", calendarId: String, eventNotes: String) {
        self.id = calendarId
        self.name = name
        self.eventNotes = eventNotes
    }
    
    init(from calendarEvent: EKEvent) {
        self.id = calendarEvent.eventIdentifier
        self.name = calendarEvent.title
        self.eventNotes = calendarEvent.notes ?? ""
    }
    
   ...
    static func loadEvents(date: Date = Date()) -> [Event] {
       ...
    }
}

I have the following View hierarchy

  1. NoteInputView which has @State var events: [Event] = []
  2. SelectEventButton which has @Binding var events: [Event] and calls Event.loadEvent() to retrieve list of events
  3. SelectEventSheet which has @Binding var events: [Event] and lets the user toggle isSelected

GitHub Gist with all relevant files

Adding notes with same events crashes...

With this setup, I attempt so save new notes in NoteInputView by calling addNote:

func addNote() -> Note {
    let selectedEvents = events.filter({ $0.isSelected })
    let note = Note(newNoteContent, events: selectedEvents)
    
    context.insert(note)
    do {
        try context.save()
    } catch {
        print(error) 
    }
    return note
}

This works for the first note after opening the app, or if every subsequent note has a different event selected. However, storing a second note with the same event crashes with the following error:

"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'events' between objects in different contexts"

(complete error see here) The error occurs at context.insert, which doesn't throw.

If I force quit the app, and then add a note with the same events as an already persisted note, no error is thrown (until a I add another note with the same event without force-quitting).

... but not because one cannot refer to the same events twice

It's not a problem of referring to the same events, as the following code also works fine for multiple notes:

func addNote() -> Note {
    // This works, despite notes also always referring to the same events
    let note = Note(newNoteContent, events: Event.loadEvents())
    
    context.insert(note)
    do {
        try context.save()
    } catch {
        print(error)
    }
    return note
}

.

... workaround? Manually adding events to the context before adding it to the notes

One workaround seems to be to add the events to the context before adding the note:

func addNote() -> Note {
    let selectedEvents = events.filter({ $0.isSelected })
    selectedEvents.forEach({context.insert($0)})

    let note = Note(newNoteContent, events: events)
    
    context.insert(note)
    do {
        try context.save()
    } catch {
        print(error)
    }
    return note
}

.

... but why?

While this works, I cannot quite make sense of this. It seems that passing events around between views may be the culprit, or that loadEvents is called in a child view. Would love some advice, since this doesn't seem like intended behavior.

SwiftData: Inserting two entities with same relationship target crashes
 
 
Q