Status 2026-10-02. Draft PR #1624 removes the lazy create. Tracked under #1755 (step 6).
What happened
A search or add on a project that does not exist creates it. POST /memories/search for a never-created (org_id, project_id) returns 200 with empty results, and afterwards the project exists: a sessions row with status active, a segment-store partition, and a vector-store collection have all been created. POST /projects/get then returns 200 for it.
Observed sequence (event backend, SQLite; PostgreSQL behaves the same):
POST /memories/search {"org_id": "manual_org", "project_id": "never_made", "query": "x", "top_k": 1, "types": ["episodic"]}
-> 200 {"status":0,"content":{"episodic_memory":{"long_term_memory":{"episodes":[]}, ...
sessions table before: [('manual_org/keep_me', 'active')]
sessions table after: [('manual_org/keep_me', 'active'), ('manual_org/never_made', 'active')]
segment_store_pt rows: 1 -> 2
The same applies after a deletion: once the deletion worker has removed a project, the next stray search or add recreates it under the same ids.
Cause, line numbers as of 231ce171 (main): both MemMachine.add_episodes (packages/server/src/memmachine_server/main/memmachine.py:714) and the episodic search path (line 773) enter episodic_memory_manager.open_or_create_episodic_memory (episodic_memory/episodic_memory_manager.py:225), whose missing-session branch (line 270) calls create_new_session and builds the memory, which in turn opens or creates the partition and collection through the event backend's service locator (long_term_memory/service_locator.py:125 and :140).
The search handler was written expecting the opposite: search_memories (server/api_v2/router.py:318) maps a RuntimeError containing "No session info found for session" to a 404 "Project does not exist", but that branch is unreachable for a missing project because the session is created before any such error could occur.
Expected
Reads and writes on a nonexistent project should fail with 404 (the mapping the search handler already tries to apply), and only POST /projects should create one. If implicit creation on add is intended, it should not extend to search, and it should not resurrect a project that was explicitly deleted.
Notes
Found by a manual end-to-end run against the server. Beyond the surprise for API users, implicit creation makes project deletion non-final: any client still issuing searches after a delete brings the project back, with fresh empty storage under the same ids.
Investigated and written by Claude (Claude Code), filed from the account of the user who commissioned the investigation.
Status 2026-10-02. Draft PR #1624 removes the lazy create. Tracked under #1755 (step 6).
What happened
A search or add on a project that does not exist creates it.
POST /memories/searchfor a never-created(org_id, project_id)returns 200 with empty results, and afterwards the project exists: asessionsrow with statusactive, a segment-store partition, and a vector-store collection have all been created.POST /projects/getthen returns 200 for it.Observed sequence (event backend, SQLite; PostgreSQL behaves the same):
The same applies after a deletion: once the deletion worker has removed a project, the next stray search or add recreates it under the same ids.
Cause, line numbers as of
231ce171(main): bothMemMachine.add_episodes(packages/server/src/memmachine_server/main/memmachine.py:714) and the episodic search path (line 773) enterepisodic_memory_manager.open_or_create_episodic_memory(episodic_memory/episodic_memory_manager.py:225), whose missing-session branch (line 270) callscreate_new_sessionand builds the memory, which in turn opens or creates the partition and collection through the event backend's service locator (long_term_memory/service_locator.py:125and:140).The search handler was written expecting the opposite:
search_memories(server/api_v2/router.py:318) maps aRuntimeErrorcontaining "No session info found for session" to a 404 "Project does not exist", but that branch is unreachable for a missing project because the session is created before any such error could occur.Expected
Reads and writes on a nonexistent project should fail with 404 (the mapping the search handler already tries to apply), and only
POST /projectsshould create one. If implicit creation on add is intended, it should not extend to search, and it should not resurrect a project that was explicitly deleted.Notes
Found by a manual end-to-end run against the server. Beyond the surprise for API users, implicit creation makes project deletion non-final: any client still issuing searches after a delete brings the project back, with fresh empty storage under the same ids.
Investigated and written by Claude (Claude Code), filed from the account of the user who commissioned the investigation.