Updated .ics calendar entries not handled correctly when synchronising with Nextcloud

HARDWARE: Sony Xperia XA2 Plus, Sony Xperia 10 iii


I have a calendar that synchronizes with Nextcloud which is used to keep a diary of all my meetings and appointments. Many of these are entered manually by me, but some are imported from .ics files sent to me as email attachments by others arranging meetings which involve me. This bug only concerns the latter situation (the .ics import).

Generally the import works perfectly for the first time in all cases. In other words somebody sends you a diary invite, you import it, and there is it correctly in your calendar. This also synchronises correctly with Nextcloud and replicates correctly across my other Sailfish phones, ipads, etc.

But, if the sender of the calendar invite then decides to change some aspect of the meeting (time date) by updating his or her original diary entry and re-sending the updated .ics file to me, then it all goes wrong.

Importing the updated .ics file into Sailfish calendar works initially - SFOS advises you that the entry already exists and asks if would you like to overwrite it (yes) - and then the original calendar entry is locally updated to the new time, date or whatever. However, when it re-synchronises with Nextcloud the locally updated version on the phone is reset to what was in the original .ics file and the updates are lost. Other SFOS and IOS devices also retain the original entry.

If you try to delete the original entry and then import the updated one on the SFOS phone, it works correctly until synchronisation with Nextcloud, whereupon the the newly imported updated entry disappears completely (as it does across all synchronised devices).

Its almost as if both the original and updated .ics files have the same index number or something and SFOS synchronisation with Nextcloud sees them to be exactly the same - so if you delete original .ics entry with index number X then, when trying to synchronise the updated entry the process says 'Ah I’ve just deleted (old) entry X, so i need to delete (updated) entry X of the phone.


You need a Nextcloud account and have calendar synchronisation set in SFOS.


  1. Import an .ics file locally on SFOS phone - it appears in calendar correctly
  2. Synchronise with Nextcloud - correct entry details are replicated across all devices
  3. Import an updated version of the same .ics file on SFOS phone - it appears in calendar correctly
  4. Synchronise with Nextcloud - The entry details are incorrectly reset to those in the original .ics file


The updated details in the .ics file should take precedence over the original details - the updated calendar entry should be displayed correctly


The original, and now incorrect, calendar entry details persist


Some Openrepos apps
Patch Manager - single patch - display emergency contact text on lock screen



I think I get why it’s behaving like that:

  • import some ICS data, creating event UID plop for instance,
  • run synchronisation, event plop is detected as a new event and send to server. As a consequence, it gets an etag etag-plop.
  • at some later synchronisations, server etag for event plop is compared with the locally stored one, and match, so no change.
  • import some modification of event plop. Internally, it deletes the incidence (and thus the associated etag) and creates a new one, obviously with the same UID plop but without etag.
  • at next synchronisation, an event plop exists on server with etag etag-plop while it also exists on device, but without etag. The synchronisation logic treats this as an event that was partially upsynced and didn’t receive its etag for network failure reasons. So it triggers a server download to force writing the etag. See notebooksyncagent.cpp#940 in buteo-sync-plugin-caldav.

I need to think how to properly solve this issue… My first idea would be to update the event on device on re-importation instead of deleting it and readding it. Like that properties like etag can be propagated to the modified version. I need to check that it cannot leave spurious old state though (like the first import ahs a description for instance, while the re-import has no mention of description. Will the update actually delete the description or leave it as it is?). Actually, I’ve no other idea at the moment. The etag handling is specific to the CalDAV protocol (in buteo-sync-plugin-caldav) and thus not known in the generic importation code (in nemo-qml-plugin-calendar), so there is no point in specifically propagating the etag in the importation code.

I guess the way to circumvent the issue at the moment would be to delete the local event, synchronise and then only re-import the modified version (and sync again). Like that the server won’t have any leftover of the initial ICS data when re-syncing.


Ah, looking better at the code, mKCal is already converting a (deletion + addition of an event sharing the same UID) as an update of this event. But internally, the update starts by deleting all custom properties of the event (thus including the etag) before recreating the custom properties for the new version of the event.

So not a solution. Back to the black board…