Repository navigation
Name users the cached Zulip user list has lost - #256
Merged
Merged
Conversation
Zulip 12.3 serves GET /users from a realm-wide cache. Creating a user deletes that cache before the creating transaction commits, so a GET /users landing in that gap caches the list without the new user. It stays missing until the next change to any user. A pinned bot minted into that gap could not be resolved or mentioned, its posts were labelled human, and mentions of it were dropped on the way in. When the cached list lacks a user id it needs, the adapter now reads GET /users with user_ids, which queries the database. For a name, it first asks Zulip's renderer to resolve @**name**, which also queries the database. Both reads happen only on a miss. list_agents and list_humans still read the cached list.
GraemeF
marked this pull request as ready for review
October 2, 2026 05:56
GraemeF
added a commit
that referenced
this pull request
Oct 2, 2026
Patch release, 0.24.2 → 0.24.3. It ships the fix that finds a newly created user Zulip's cached user list has missed (#256), the fix that stops an unsubscribe from one topic dropping the seat's other topics in that channel (#257), and the PyJWT security bump in the Hermes lockfile (#253). Merge #256 first. The notes in `RELEASE-NOTES/0.24.3.md` become the GitHub Release body. Merging fires the tag and npm publish.
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.
Zulip 12.3 serves
GET /usersfrom a realm-wide cache. Creating a user deletes that cache inside the creating transaction, before it commits. AGET /usersthat lands in that gap caches the list without the new user, and the user stays missing until the next change to any user. The source isget_realm_user_dictsinzerver/models/users.pyandflush_user_profileinzerver/lib/cache.py.A newly minted pinned bot that hits this gap is invisible to commy.
resolvereturns nothing for it,@**name**is refused, and its posts arrive labelledhuman. Mentions of it would also be dropped on the way in, so it would not wake on its own mention.When the cached list lacks a user id it needs, the adapter now reads
GET /users?user_ids=…, which queries the database. To place a name,resolveand the outbound mention check first askPOST /messages/renderto resolve@**name**, which also queries the database. Both reads happen only on a miss, and a history or catch-up page asks once for all of its missing ids.What a reviewer should know:
list_agentsandlist_humansstill read the cached list, because they need all of it.human. They send only a small fraction of messages.