Answering one occurrence leaves an empty entry in the organizer's calenda

Issue Description

Answering one occurrence leaves an empty entry in the organizer’s calendar

Expected Behavior

that occurrence shows the meeting as usual, with B marked as declined.

Actual Behavior

it shows twice: once normally, and once as an untitled entry with no time, no length and no other guests.

Reproduction Steps

1 User A creates a weekly meeting and invites user B (both on the same server).
2 User B declines just one occurrence.
3 User A opens their calendar.

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

in crates/groupware/src/scheduling/inbound.rs (lines 505–536), when the reply is for an occurrence that has no separate entry yet, the new entry is built only from the reply. Only ORGANIZER, ATTENDEE, UID, DTSTAMP, SEQUENCE and RECURRENCE-ID are copied. It should start from a copy of the organizer’s own event instead.

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

This isn’t covered in the current docs. A community member or staff member will follow up.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

This has been just fixed in the v1.0.0 branch but the change can’t be backported to v0.16 at the moment. v1.0.0 is expected for late October/early November.

Related, on v0.16.23: declining a single occurrence as the attendee by patching only the own status inside the override fails:

CalendarEvent/set, sendSchedulingMessages: true
update: { "<id>": { "recurrenceOverrides": {
  "2027-01-20T09:00:00": { "participants/a1/participationStatus": "declined" } } } }

Result: invalidProperties, “Multiple organizers found in iCalendar object”. Putting the complete participants object into the override works. Could you check whether the v1.0 branch also accepts the patch form?

(Tested on a test instance; written with the help of an AI assistant.)

Also fixed in v1.0.0.

Thanks for checking both cases.

Good to know they’re fixed in 1.0

we’ll work around it on 0.16 until then.

We hit the same empty entry on 0.16.25 with external attendees on Google Calendar. Two effects aren’t in this thread yet, so the v1.0.0 fix can be checked against them:

  1. Every later reply for that occurrence is dropped. After the first attendee’s REPLY creates the stub, a second attendee’s REPLY for the same RECURRENCE-ID matches the stub. The stub’s only ATTENDEE is the first replier, so the second sender isn’t found, and handle_reply returns SenderIsNotParticipant:

DEBUG iTIP message error (calendar.itip-message-error) … details = “Sender “[email protected]” is not a participant”

The organizer’s object stays unchanged, but the mail still lands in the inbox. The event is logged at Debug level, so nothing shows at info. Reproduced on a clean v0.16.25 with three local accounts:

  • A accepts one untouched instance, and the stub appears.
  • B accepts the same instance. The object is byte-identical afterwards, and B is still NEEDS-ACTION on the master.
  • Control: for an instance the organizer had already overridden, both replies merge correctly.
  1. The stub distorts expansion. calcard falls back to the RECURRENCE-ID when DTSTART is missing, and runs a missing end to 23:59:59. Free/busy therefore shows that occurrence as busy until midnight. The stub also copies the reply’s SEQUENCE, and overrides are matched on (SEQUENCE, RECURRENCE-ID). If that differs from the master’s, expansion emits both the master instance and an orphan.

tests/resources/itip/rfc6638_recurring.txt currently expects the stub as the organizer-side result, so that fixture will need updating too. Could you confirm that the 1.0.0 change builds the override from the master, with its properties, DTSTART from the RECURRENCE-ID and the full attendee list? Happy to test a prerelease against the repro above.