Skip to content

[Bug]: Deleting a project deletes the org-level semantic set every project shares, and keeps the project's tagged sets #1732

Description

@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 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:

  1. 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.
  2. 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.

  1. 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).
  2. 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.
  3. 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.

Activity

  1. added theissue type on Oct 1, 2026
  2. added
    multiuserMulti-user support: isolation and behavior across users, orgs and projects
    on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    multiuserMulti-user support: isolation and behavior across users, orgs and projects

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions