fix(cli): keep every result in entity delete, not just the last#5936
Merged
kartik-mem0 merged 1 commit intoJun 29, 2026
Merged
Conversation
delete_entities looped over each entity but reassigned a single `result` variable, so a multi-entity delete (e.g. --user-id and --agent-id together) returned only the last entity's API response. Under `mem0 entity delete --output json` the other deletions were silently dropped from the output. Collect responses into a dict keyed by entity type. No data is lost and the `-> dict` return type is preserved. Adds a backend test module covering multi-entity, single-entity, and the no-entity ValueError; the multi-entity case fails without the fix. Closes mem0ai#5935
Contributor
Author
|
@kartik-mem0 small CLI fix with tests. Noted a minor JSON-shape question in the description. Quick review when you can, thanks. |
kartik-mem0
approved these changes
Jun 29, 2026
Contributor
|
hey @abhay-codes07 thank you for contribution can you confirm if this issues are also in the ts cli and raise the issue for them? #5933, #5931 and the above one! thanks! |
This was referenced Jun 29, 2026
bug(cli-node):
entity delete returns only the last entity's response (TS counterpart of #5935)
#5969
Closed
Contributor
Author
|
@kartik-mem0 thanks! Checked the Node/TS CLI for all three:
So only the entity delete one needed a fix on the TS side. |
14 tasks
RudrenduPaul
added a commit
to RudrenduPaul/memtrust
that referenced
this pull request
Jul 12, 2026
No adapter method exists for deleting a memory or entity, so no eval can exercise the real, merged multi-entity-delete truncation bug class (mem0ai/mem0#5936, #5970: client-side aggregation silently keeping only the last response instead of all N). Add an abstract delete() to MemoryBackendAdapter plus a concrete default delete_many() that loops over delete() and aggregates one DeleteResult per input id, in order, even when some deletes fail -- this is the primitive an eval needs to construct that reproduction and prove the aggregation itself doesn't truncate. Implement delete() for real against Mem0 (DELETE /v1/memories/{id}/), Zep/Graphiti, and OpenViking following each adapter's existing store/query/update HTTP conventions and documented confidence level. MemPalace has no confirmed delete/forget primitive in its vendor surface, so its delete() raises a clearly-documented BackendAPIError instead of guessing an unverified method name. Built by Rudrendu Paul and Sourav Nandy, developed with Claude Code
RudrenduPaul
added a commit
to RudrenduPaul/memtrust
that referenced
this pull request
Jul 16, 2026
No adapter method exists for deleting a memory or entity, so no eval can exercise the real, merged multi-entity-delete truncation bug class (mem0ai/mem0#5936, #5970: client-side aggregation silently keeping only the last response instead of all N). Add an abstract delete() to MemoryBackendAdapter plus a concrete default delete_many() that loops over delete() and aggregates one DeleteResult per input id, in order, even when some deletes fail -- this is the primitive an eval needs to construct that reproduction and prove the aggregation itself doesn't truncate. Implement delete() for real against Mem0 (DELETE /v1/memories/{id}/), Zep/Graphiti, and OpenViking following each adapter's existing store/query/update HTTP conventions and documented confidence level. MemPalace has no confirmed delete/forget primitive in its vendor surface, so its delete() raises a clearly-documented BackendAPIError instead of guessing an unverified method name. Built by Rudrendu Paul and Sourav Nandy, developed with Claude Code
RudrenduPaul
added a commit
to RudrenduPaul/memtrust
that referenced
this pull request
Jul 16, 2026
No adapter method exists for deleting a memory or entity, so no eval can exercise the real, merged multi-entity-delete truncation bug class (mem0ai/mem0#5936, #5970: client-side aggregation silently keeping only the last response instead of all N). Add an abstract delete() to MemoryBackendAdapter plus a concrete default delete_many() that loops over delete() and aggregates one DeleteResult per input id, in order, even when some deletes fail -- this is the primitive an eval needs to construct that reproduction and prove the aggregation itself doesn't truncate. Implement delete() for real against Mem0 (DELETE /v1/memories/{id}/), Zep/Graphiti, and OpenViking following each adapter's existing store/query/update HTTP conventions and documented confidence level. MemPalace has no confirmed delete/forget primitive in its vendor surface, so its delete() raises a clearly-documented BackendAPIError instead of guessing an unverified method name. Built by Rudrendu Paul and Sourav Nandy, developed with Claude Code
RudrenduPaul
added a commit
to RudrenduPaul/memtrust
that referenced
this pull request
Jul 16, 2026
No adapter method exists for deleting a memory or entity, so no eval can exercise the real, merged multi-entity-delete truncation bug class (mem0ai/mem0#5936, #5970: client-side aggregation silently keeping only the last response instead of all N). Add an abstract delete() to MemoryBackendAdapter plus a concrete default delete_many() that loops over delete() and aggregates one DeleteResult per input id, in order, even when some deletes fail -- this is the primitive an eval needs to construct that reproduction and prove the aggregation itself doesn't truncate. Implement delete() for real against Mem0 (DELETE /v1/memories/{id}/), Zep/Graphiti, and OpenViking following each adapter's existing store/query/update HTTP conventions and documented confidence level. MemPalace has no confirmed delete/forget primitive in its vendor surface, so its delete() raises a clearly-documented BackendAPIError instead of guessing an unverified method name. Built by Rudrendu Paul and Sourav Nandy, developed with Claude Code
RudrenduPaul
added a commit
to RudrenduPaul/memtrust
that referenced
this pull request
Jul 18, 2026
No adapter method exists for deleting a memory or entity, so no eval can exercise the real, merged multi-entity-delete truncation bug class (mem0ai/mem0#5936, #5970: client-side aggregation silently keeping only the last response instead of all N). Add an abstract delete() to MemoryBackendAdapter plus a concrete default delete_many() that loops over delete() and aggregates one DeleteResult per input id, in order, even when some deletes fail -- this is the primitive an eval needs to construct that reproduction and prove the aggregation itself doesn't truncate. Implement delete() for real against Mem0 (DELETE /v1/memories/{id}/), Zep/Graphiti, and OpenViking following each adapter's existing store/query/update HTTP conventions and documented confidence level. MemPalace has no confirmed delete/forget primitive in its vendor surface, so its delete() raises a clearly-documented BackendAPIError instead of guessing an unverified method name. Built by Rudrendu Paul and Sourav Nandy, developed with Claude Code
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.
Linked Issue
Closes #5935
Description
delete_entities()walks every entity it's asked to delete, but it writes each API response into oneresultvariable that gets overwritten on the next pass — so only the last entity's response makes it back to the caller:That matters because
mem0 entity deletelets you pass--user-id,--agent-id,--app-id, and--run-idtogether, andcmd_entities_deleteprints this value straight out under--output json. Delete two entities and the JSON only shows one — anything scripting against that output silently loses the rest.The fix collects each response into a dict keyed by entity type (
{"user": {...}, "agent": {...}}). Nothing is dropped, the deletes themselves were always happening (one request each), and the-> dictreturn type stays intact. Single-entity deletes just return a one-key dict.Type of Change
Breaking Changes
The JSON shape of
mem0 entity delete --output jsonchanges from a single raw API response to a map keyed by entity type. This only affects the multi-entity case (which was lossy before) and the human/agent output modes are unaffected, so I've treated it as a bug fix rather than a breaking change — happy to adjust if you'd prefer to preserve the single-entity raw shape.Test Coverage
Added
tests/test_platform_backend.pycovering multi-entity (fails without the fix), single-entity, and the no-entityValueError._requestis patched, so no network calls. Full CLI suite passes andruff checkis clean.Checklist