fix(mem0): scope prefetch search and result cache by user_id - #44
Merged
Conversation
queue_prefetch() was ignoring its user_id argument and always searching
under self._user_id (set at initialize() time). In shared gateway
sessions where the cached AIAgent is reused across participants, this
caused cross-user memory leakage: one user could receive prefetched
memories originally fetched for a different user.
Fixes:
- queue_prefetch(): capture effective_user_id before spawning thread,
pass {"user_id": effective_user_id} directly instead of self._read_filters()
- Store prefetch result as (user_id, text) tuple so the consumer can
verify ownership
- prefetch(): discard the cached result when its user_id does not match
the current request — prevents stale cross-user results from leaking
Addresses Codex PR#33 P1 review comment.
…njection When queue_prefetch gets results but all memory fields are empty, cached becomes (user_id, ""). prefetch was treating any truthy tuple as valid, returning "## Mem0 Memory " with no bullets. Add not cached[1] guard. Fixes Cursor Bugbot finding on PR #43.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
🔎 Lint report:
|
This was referenced Jun 28, 2026
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.
Summary
queue_prefetch()was ignoring itsuser_idargument and searching underself._user_id(set once atinitialize()time). In shared gateway sessions where the cachedAIAgentis reused across participants, this caused cross-user memory leakage.prefetch()returned cached results without checking which user they were fetched for, so a result queued for User A could be injected into User B's next prompt.Changes
queue_prefetch(): captureeffective_user_id = user_id or self._user_idbefore spawning the background thread; pass{"user_id": effective_user_id}directly toclient.search()instead ofself._read_filters(); store result as(user_id, text)tuple.prefetch(): discard the cached result when its owneruser_iddoes not match the current caller — prevents stale cross-user results from leaking into the wrong session.__init__: initialize_prefetch_resulttoNoneinstead of""to match the new tuple-or-None shape.(user_id, "")) now return""rather than injecting a bare## Mem0 Memoryheader with no bullets.Addresses Codex PR#33 P1 review comment: Scope prefetched memory by current user.
All CI checks passed on the original draft PR #43.
Generated by Claude Code
Note
Medium Risk
Touches per-turn memory injection in multi-user gateway paths; behavior change is intentional isolation with limited surface area in one provider.
Overview
Fixes cross-user memory leakage when a shared
Mem0MemoryProviderserves multiple gateway participants: background prefetch now searches and caches under the current turn’suser_id, not onlyself._user_idfrominitialize().queue_prefetch()resolveseffective_user_id = user_id or self._user_id, passes{"user_id": effective_user_id}toclient.search()(instead ofself._read_filters()), and stores the cache as(user_id, bullet text).prefetch()returns cached bullets only when the tuple’s user matches the caller; mismatches or empty text yield""so User A’s prefetch cannot appear in User B’s prompt and empty results do not inject a bare## Mem0 Memoryheader.__init__sets_prefetch_resulttoNonefor the tuple-or-None cache shape.Reviewed by Cursor Bugbot for commit 3a3d3ce. Configure here.