Skip to content

PARTSTAT change on a single occurrence of a recurring event triggers METHOD:REQUEST re-invite to all other attendees #60452

@ndo84bw

Description

@ndo84bw

Summary

When an attendee accepts or declines a single occurrence of a recurring event, a recurrence exception (VEVENT with RECURRENCE-ID) is created. This modification to the calendar object causes Nextcloud to send a METHOD:REQUEST email to all other attendees, even though nothing changed for them.

This does not happen for single (non-recurring) events, where a PARTSTAT change correctly results in only a METHOD:REPLY to the organizer.

Related: nextcloud/calendar#6535 (notification spam), nextcloud/calendar#7771 (accept creates recurrence exception instead of updating master PARTSTAT), nextcloud/calendar#7850 (recurring event exception handling).

Setup

  • Nextcloud: 33.0.2
  • Calendar app: 6.2.2
  • dav: 1.36.0
  • All users on the same instance, invited via the internal user picker (principal-based scheduling).
  • Attendees use Thunderbird 128.x via CalDAV.

Reproduction

Case A: Attendee declines a single occurrence

  1. User A creates a weekly recurring event "Weekly 3x" (3 occurrences), adds User B and User C as attendees via the user picker.
  2. User B accepts the entire series via Thunderbird iMIP.
  3. User C accepts the entire series via Thunderbird iMIP.
  4. User B declines only the 2026-05-12 occurrence via Thunderbird ("Decline" on that single instance).

What User A (organizer) receives - correct:

A METHOD:REPLY with RECURRENCE-ID for 2026-05-12 and PARTSTAT=DECLINED. The mail says "User B has declined your invitation" with the correct date. This is perfect.

What User C (other attendee) receives - incorrect:

A METHOD:REQUEST re-invite for the entire series:

METHOD:REQUEST

BEGIN:VEVENT
UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
DTSTART;TZID=Europe/Berlin:20260505T113000
RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TU
SUMMARY:Weekly 3x
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-b@example.com
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-c@example.com
ORGANIZER;CN=admin:mailto:user-a@example.com
END:VEVENT
BEGIN:VEVENT
UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
DTSTART;TZID=Europe/Berlin:20260512T113000
RECURRENCE-ID;TZID=Europe/Berlin:20260512T113000
ATTENDEE;PARTSTAT=DECLINED:mailto:user-b@example.com
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-c@example.com
ORGANIZER;CN=admin:mailto:user-a@example.com
END:VEVENT

Thunderbird at User C displays: "admin has invited you to Weekly 3x"
Nextcloud mail body at User C: "admin would like to invite you to 'Weekly 3x'."

User C already accepted. Nothing changed for User C. This email provides no useful information.

Case B: Attendee accepts a single occurrence

  1. User A creates a daily recurring event, adds User B and User C.
  2. User B accepts the series via Thunderbird.
  3. User C accepts a single occurrence via the Nextcloud Calendar web UI (which creates a recurrence exception due to Missing “apply to all/this/this and following” options for recurring events in calendar #12142 calendar#7771).

Result: User B receives a METHOD:REQUEST re-invite for the entire series. The mail says "admin would like to invite you to 'Daily Test'" with the date of the first occurrence (which is in the past).

Case C: Attendee removes event from calendar

Same setup as Case B. User C (attendee) deletes the event in Thunderbird.

Result: User B again receives a METHOD:REQUEST re-invite.

Control test: Single (non-recurring) event

  1. User A creates a single event "Admin +2", adds User B and User C.
  2. User B accepts via Thunderbird.

Result: User C does not receive any email. Only User A receives the METHOD:REPLY. This is the correct behavior.

Pattern

Case Other attendee gets re-invite? Correct?
Single event: attendee accepts No Yes
Recurring series: attendee accepts entire series No Yes
Recurring series: attendee accepts single instance Yes No
Recurring series: attendee declines single instance Yes No
Recurring series: attendee deletes event Yes No

The pattern is clear: whenever a PARTSTAT change on a recurring event creates a recurrence exception (VEVENT with RECURRENCE-ID), Nextcloud treats the modified calendar object as an organizer-initiated update and sends METHOD:REQUEST to all attendees. Operations that do not create exceptions (accepting the whole series, or any operation on a single event) behave correctly.

Expected behavior

A PARTSTAT change by one attendee should only generate a METHOD:REPLY to the organizer. Other attendees should not receive any email, regardless of whether the change creates a recurrence exception internally.

Impact

On a multi-user instance, a recurring meeting with N attendees generates up to N-1 unnecessary re-invite emails every time any single attendee changes their response to a single occurrence. With ~600 users, this creates significant email noise that causes users to ignore calendar notifications entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions