Issue Description
Creating a calendar event through CalendarEvent/set with the uid property omitted succeeds, but Stalwart stores the event without a UID.
This affects both ordinary and recurring events. For recurring events, the missing UID makes it difficult or impossible for clients to associate expanded occurrences with the underlying series. It also produces malformed CalDAV data for clients such as Thunderbird, which rely on UID as the stable identity of an event or recurrence series.
The affected code path appears to validate uniqueness using:
assert_is_unique_uid(self, account_id, ical.uids().next())
When ical.uids().next() returns None, the uniqueness check succeeds, and the event is stored without generating a UID.
Expected Behavior
When uid is omitted from a newly created CalendarEvent, Stalwart should generate a new globally unique UID before storing the event.
The JMAP Calendars draft states:
If omitted on create, the server MUST set the following properties:
@typeMUST be set to"Event"uidMUST be set to a new globally unique identifier, such as a UUIDcreatedMUST be set to the current date-time
This is specified in the CalendarEvent/set creation semantics in draft-ietf-jmap-calendars-26.
Actual Behavior
Stalwart accepts the creation request but stores and returns the event without a uid.
For example, the following recurring event was successfully created:
{
"using": [
"urn:ietf:params:jmap:core",
"urn:ietf:params:jmap:calendars"
],
"methodCalls": [
[
"CalendarEvent/set",
{
"accountId": "c",
"create": {
"event": {
"@type": "Event",
"calendarIds": {
"c": true
},
"title": "Test event",
"start": "2026-07-25T09:00:00",
"duration": "PT1H",
"timeZone": "Pacific/Auckland",
"recurrenceRule": {
"frequency": "daily",
"interval": 1
}
}
}
},
"create"
]
]
}
A subsequent CalendarEvent/get returned the stored base event without a UID:
{
"title": "Test event",
"duration": "PT3600S",
"recurrenceRule": {
"frequency": "daily",
"interval": 1
},
"timeZone": "Pacific/Auckland",
"start": "2026-07-25T09:00:00",
"showWithoutTime": false,
"@type": "Event",
"id": "ta",
"calendarIds": {
"c": true
},
"isDraft": false,
"isOrigin": true
}
The expected generated uid property is absent.
Reproduction Steps
- Configure an account with JMAP Calendars enabled.
- Send a
CalendarEvent/setcreate request. - Include the required event properties but omit
uid. - Confirm that the create operation succeeds.
- Fetch the created event using
CalendarEvent/get. - Observe that the returned event has no
uid. - Optionally create the event with a recurrence rule.
- Query it with
expandRecurrences: true. - Observe that the expanded occurrences also have no UID, making recurrence-series association unreliable.
Relevant Log Output
No log output
Stalwart Version
v0.16.x
Installation Method
Docker
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
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
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on