fix(invites): read RSVPs through zone changes, not a zone query - #352
Open
MrJarnould wants to merge 2 commits into
Open
MrJarnould wants to merge 2 commits into
MrJarnould wants to merge 2 commits into
Conversation
`rsvps()` raised for every event you host. It issued a per-zone
`records/query`, and an event's own zone rejects that:
"syncToken operations supported only in SyncZone"
Only events shared with you worked, because their zones are owned
elsewhere. Live, all four hosted events returned 400 and the one shared
event returned its responses.
The zone's changes feed does support these zones -- it is what timlaing#339 uses to
enumerate the shared scope, and a per-zone changes call returns an event's
EventDetails, RSVP and cloudkit.share records together. `rsvps()` now reads
that and filters to RSVP records, asking for them via desiredRecordTypes
and filtering anyway, since a projection is a request rather than a
guarantee. Paging comes free from iter_changes().
Not a regression from timlaing#339: this path dates from timlaing#246 and was unreachable
while events() still raised on every account, so nobody got far enough to
call it.
Verified live across both scopes: the four hosted events now return their
responses and the shared event returns the same two as before.
Closes timlaing#350
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 11 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The first commit fixed rsvps() and missed its sibling. `_fetch_event_full` made the same rejected per-zone query, and swallowed the failure into a debug log -- so `event()` returned every hosted event with `rsvps = ()` and nothing said why. Both now go through one `_rsvp_records()` helper, so there is no second place to forget. This turns out to be the root of a bug that looked unrelated. `rsvp()` locates the existing response in `event.rsvps` to decide between create and update. With hydration silently empty it never found one, always chose create, and CloudKit answered CONFLICT -- which was itself discarded (timlaing#353) and reported as "modify response missing record". Verified live on an event with no guests: `event()` now hydrates its RSVP, and `rsvp()` changes the record. GOING -> MAYBE with a message, then back. Before this, that write did nothing at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 4, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed change
InvitesService.rsvps(event)raises for every event you host. It works only for events sharedwith you.
It issues a per-zone
records/query, and an event's own zone rejects that:Against a live account, before:
Shared events work because their zones are owned elsewhere; your own event zones do not
support being queried at all.
The changes feed does support them — it is the same mechanism #339 introduced for enumerating
the shared scope, and a per-zone
changescall returns an event'sEventDetails,RSVPandcloudkit.sharerecords together.rsvps()now reads that and filters toRSVP.Two details:
desiredRecordTypesasks Apple for the RSVP records alone, and the filter is kept anyway,because a projection is a request rather than a guarantee.
iter_changes(), which fix(invites): read the shared scope zone by zone #339 already added and which follows the synctoken to the end.
Not a regression from #339. This path dates from #246. It was simply unreachable while
events()raised on every account — nobody got far enough to callrsvps().Type of change
Additional information
Cut from
main, touching onlypyicloud/services/invites/service.pyandtests/test_invites.py.Testing. 936 tests pass on Python 3.10, 3.11, 3.12, 3.13 and 3.14, run locally. Three are
new and one existing test was rewritten onto the new mechanism — its fixture records are the
same shape a changes page returns, so it still describes what Apple sends. Four fail against
main.Verified live across both scopes, which is the part that matters here, since the whole bug
is a difference between them:
The shared event returns the same two responses as before, so the path that already worked is
unchanged.
How I found it. While building
cancel()andpublish()(#351), checking which events hadno guests before testing a write against one. Names in the output above are redacted where they
belong to someone else.
Checklist
If user exposed functionality or configuration variables are added/changed:
🤖 Generated with Claude Code