mem0ai/mem0 · error · RuntimeError
Cannot reset a closed SQLiteManager
Error message
Cannot reset a closed SQLiteManager
What it means
SQLiteManager.reset() raises RuntimeError when self.connection is falsy — the manager was closed via close() (or never fully opened) and its SQLite handle is gone. reset() drops the history and messages tables inside a transaction; without a live connection there is nothing to drop, so it refuses rather than crash with an opaque sqlite error. The docstring states the contract: the caller is expected to replace this instance after use.
Source
Thrown at mem0/memory/storage.py:329
""",
(session_scope, limit),
)
rows = cur.fetchall()
return [
{
"role": r[0],
"content": r[1],
"name": r[2],
"created_at": r[3],
}
for r in rows
]
def reset(self) -> None:
"""Drop both tables. Caller is expected to replace this instance."""
if not self.connection:
raise RuntimeError("Cannot reset a closed SQLiteManager")
with self._lock:
try:
self.connection.execute("BEGIN")
self.connection.execute("DROP TABLE IF EXISTS history")
self.connection.execute("DROP TABLE IF EXISTS messages")
self.connection.execute("COMMIT")
except Exception as e:
self.connection.execute("ROLLBACK")
logger.error(f"Failed to reset tables: {e}")
raise
def close(self) -> None:
if self.connection:
self.connection.close()
self.connection = None
def __del__(self):
self.close()View on GitHub (pinned to 001c235229)
Solutions
- Create a fresh SQLiteManager (or a fresh Memory) and reset that, since reset() is terminal anyway — the instance must be replaced
- Ensure reset() runs before close() in shutdown/teardown ordering
- Guard calls: if manager.connection is None, skip reset or reopen the manager first
Example fix
# before manager.close() manager.reset() # RuntimeError # after manager.reset() # reset first manager.close() # then close; or simply discard the manager and build a new one
Defensive patterns
Strategy: validation
Validate before calling
if getattr(manager, "connection", None) is None:
manager = SQLiteManager(...) # rebuild instead of resetting a closed one Try / catch
try:
manager.reset()
except RuntimeError:
pass # already closed; nothing to reset Prevention
- Order teardown: reset() then close(), never the reverse
- Treat a closed manager as single-use: build a new instance
- Centralize lifecycle transitions in one shutdown routine
When it happens
Trigger: Calling manager.reset() after manager.close(); resetting inside Memory.reset() when the underlying SQLiteManager was already closed (e.g. memory.close() then memory.reset()); holding a stale manager reference across an application shutdown/restart cycle.
Common situations: Test teardown code that closes the storage then a fixture-level reset runs afterwards; long-lived services that close() on shutdown but have a background task that later triggers reset; calling reset() twice where the first path closed the connection.
Related errors
- AND filter value must be a list of filter dicts, got ${typeo
- OR filter value must be a list of filter dicts, got ${typeof
- NOT filter value must be a list of filter dicts, got ${typeo
- Vector dimension mismatch. Expected ${this.dimension}, got $
- Query dimension mismatch. Expected ${this.dimension}, got ${
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/34d5d07d60954ceb.
Report an issue: GitHub.