Describe the bug
Deleting a project picks the wrong semantic sets. It deletes every feature in the org-level default set, which all projects of the org share, and it leaves the features in the project's own tagged sets in place.
Code at 82b6c6f58, paths under packages/server/src/memmachine_server/:
server/api_v2/router.py:268-288: POST /projects/delete calls MemMachine.delete_session. That call queues the session (main/memmachine.py:582-608), and the worker runs _delete_queued_session (:357-367).
main/memmachine.py:390-392: _delete_session_semantic_memory is semantic_memory_manager.delete_feature_set(session_data=session), with no set metadata.
semantic_memory/semantic_session_manager.py:284-301: delete_feature_set resolves set ids through _get_set_ids_str_from_metadata(metadata=None) (:367-400) and deletes every feature in them.
- With no metadata,
_get_set_id_entries (:329-365) skips every set type that has tags (:351), so the project's tagged sets are not included.
_generate_default_sets (:721-763) always adds the org-level default set (project_id=None, :729-739) next to the project's default set (:754-763).
The API documents the org-level set as shared: "Org-level sets are shared across all projects within the organization" (packages/common/src/memmachine_common/api/doc.py:529-532). Deleting a project is documented to remove that project's data (doc.py:710-719), and docs/api_reference/python/project_api.mdx:45-48 says it removes "all associated episodic and semantic data".
So deleting project P of org O causes two problems:
- Every feature in O's org-level default set is deleted, including features that came from other projects of O. Every remaining project of O searches that set (
_generate_default_sets), so they all lose it.
- Features in P's project-scoped tagged sets (for example
mem_other_set_org_O_project_P_1_<hash>__team_eng) survive. Set ids are deterministic, so a new project created with the same org_id/project_id sees them again.
The org-level user sets (one per producer_id) are not touched, which matches neither reading of what "delete the project" should do to org-level data.
Steps to reproduce
Measured on 82b6c6f58 with SemanticSessionManager, SemanticService, VectorStoreSemanticStorage (sqlite-vec) and SemanticConfigStorageSqlAlchemy on SQLite files, plus a stand-in embedder. The deletion step is the exact call from memmachine.py:392.
- Org
acme, project p1: add a category to the org-level default set (the /memories/semantic/category path), then add a feature to that set (the /memories/semantic/feature path).
- Org
acme, project p2: add a feature to its default project set. Create a project-level set type with tag team (/memories/semantic/set_type), get the set id for team=eng (/memories/semantic/set_id/get), add a category to it, and add a feature to it.
- Delete project
acme/p2: await semantic_session_manager.delete_feature_set(session_data=<acme/p2>).
Output:
org set mem_set_type_org_acme_0_46b9dd2b0ba8__ ['written by p1 into the org set']
p2 set mem_project_set_org_acme_project_p2_0_46b9dd2b0ba8__ ['p2 default set']
team set mem_other_set_org_acme_project_p2_1_05ab79662e20__team_eng ['p2 team=eng set']
--- after deleting project acme/p2 ---
org set []
p2 set []
team set ['p2 team=eng set']
p1 sets searched: ['mem_set_type_org_acme_0_46b9dd2b0ba8__', 'mem_project_set_org_acme_project_p1_0_46b9dd2b0ba8__']
With the shipped defaults (default_org_categories: []), ingestion extracts nothing into the org-level set. So part 1 shows up once an operator configures org categories, or once a caller adds a category or feature to the org-level set through the API. Part 2 needs only a project-level set type with tags. The full POST /projects/delete path through the HTTP server was not run.
Expected behavior
Deleting a project deletes the features in the sets scoped to that project: its default project set and every project-level tagged set under its org_id/project_id. It leaves org-level sets alone. The per-set configuration of the deleted sets (categories, disabled categories, set-type mappings) goes too, so a later project with the same ids starts empty.
Environment
- MemMachine
main at 82b6c6f584c13ff7ca278905ad1533712dd4bb18
- Python 3.12, macOS, SQLite stores
Additional context
The deletion worker has other open issues: #1575 (semantic memory disabled), #1577 (project in use) and #1728 (deletion creates storage first). This one concerns which sets the deletion targets. Enumerating a project's tagged sets by prefix is not reliable today because set ids are ambiguous (#1716).
🤖 Written by Claude Code (Claude Opus 5.5) on behalf of @edwinyyyu.
Describe the bug
Deleting a project picks the wrong semantic sets. It deletes every feature in the org-level default set, which all projects of the org share, and it leaves the features in the project's own tagged sets in place.
Code at
82b6c6f58, paths underpackages/server/src/memmachine_server/:server/api_v2/router.py:268-288:POST /projects/deletecallsMemMachine.delete_session. That call queues the session (main/memmachine.py:582-608), and the worker runs_delete_queued_session(:357-367).main/memmachine.py:390-392:_delete_session_semantic_memoryissemantic_memory_manager.delete_feature_set(session_data=session), with no set metadata.semantic_memory/semantic_session_manager.py:284-301:delete_feature_setresolves set ids through_get_set_ids_str_from_metadata(metadata=None)(:367-400) and deletes every feature in them._get_set_id_entries(:329-365) skips every set type that has tags (:351), so the project's tagged sets are not included._generate_default_sets(:721-763) always adds the org-level default set (project_id=None,:729-739) next to the project's default set (:754-763).The API documents the org-level set as shared: "Org-level sets are shared across all projects within the organization" (
packages/common/src/memmachine_common/api/doc.py:529-532). Deleting a project is documented to remove that project's data (doc.py:710-719), anddocs/api_reference/python/project_api.mdx:45-48says it removes "all associated episodic and semantic data".So deleting project P of org O causes two problems:
_generate_default_sets), so they all lose it.mem_other_set_org_O_project_P_1_<hash>__team_eng) survive. Set ids are deterministic, so a new project created with the sameorg_id/project_idsees them again.The org-level user sets (one per
producer_id) are not touched, which matches neither reading of what "delete the project" should do to org-level data.Steps to reproduce
Measured on
82b6c6f58withSemanticSessionManager,SemanticService,VectorStoreSemanticStorage(sqlite-vec) andSemanticConfigStorageSqlAlchemyon SQLite files, plus a stand-in embedder. The deletion step is the exact call frommemmachine.py:392.acme, projectp1: add a category to the org-level default set (the/memories/semantic/categorypath), then add a feature to that set (the/memories/semantic/featurepath).acme, projectp2: add a feature to its default project set. Create a project-level set type with tagteam(/memories/semantic/set_type), get the set id forteam=eng(/memories/semantic/set_id/get), add a category to it, and add a feature to it.acme/p2:await semantic_session_manager.delete_feature_set(session_data=<acme/p2>).Output:
With the shipped defaults (
default_org_categories: []), ingestion extracts nothing into the org-level set. So part 1 shows up once an operator configures org categories, or once a caller adds a category or feature to the org-level set through the API. Part 2 needs only a project-level set type with tags. The fullPOST /projects/deletepath through the HTTP server was not run.Expected behavior
Deleting a project deletes the features in the sets scoped to that project: its default project set and every project-level tagged set under its
org_id/project_id. It leaves org-level sets alone. The per-set configuration of the deleted sets (categories, disabled categories, set-type mappings) goes too, so a later project with the same ids starts empty.Environment
mainat82b6c6f584c13ff7ca278905ad1533712dd4bb18Additional context
The deletion worker has other open issues: #1575 (semantic memory disabled), #1577 (project in use) and #1728 (deletion creates storage first). This one concerns which sets the deletion targets. Enumerating a project's tagged sets by prefix is not reliable today because set ids are ambiguous (#1716).
🤖 Written by Claude Code (Claude Opus 5.5) on behalf of @edwinyyyu.