MemPalace/mempalace · error · CollectionNotInitializedError
{collection_name}
Error message
{collection_name} What it means
`CollectionNotInitializedError` carrying just the collection name, raised from `SQLiteExactCollection._collection_id`. It means the collection row is missing from the `collections` table even though a collection object exists — the handle connected fine, but the name was never created (or was deleted) in this database file.
Source
Thrown at mempalace/backends/sqlite_exact.py:322
self._ensure_open()
cur = self._handle.conn.cursor()
try:
yield cur
except Exception:
self._handle.conn.rollback()
raise
else:
self._handle.conn.commit()
finally:
cur.close()
def _collection_id(self, cur) -> int:
row = cur.execute(
"SELECT id FROM collections WHERE name = ?",
(self._collection_name,),
).fetchone()
if row is None:
raise CollectionNotInitializedError(self._collection_name)
return int(row[0])
def _collection_dimension(self, cur, collection_id: int) -> Optional[int]:
row = cur.execute(
"SELECT dimension FROM collections WHERE id = ?",
(collection_id,),
).fetchone()
if row is None or row[0] is None:
return None
return int(row[0])
def _ensure_collection_dimension(self, cur, collection_id: int, dims: list[int]) -> None:
distinct = {int(dim) for dim in dims}
if not distinct:
return
if len(distinct) > 1:
raise DimensionMismatchError(
f"sqlite_exact collection {self._collection_name!r} cannot mix "View on GitHub (pinned to 06cb6987f0)
Solutions
- Re-obtain the collection with `create=True` after the underlying db changes: `col = backend.get_collection(palace, name, create=True)`.
- Verify you are pointing at the same palace path that the handle was created from (print both paths).
- Do not reuse collection handles after `delete_collection`; fetch a fresh one.
- If a writer crashed mid-create, the transaction rolled back — simply call get_collection(create=True) again.
Example fix
# before col = backend.get_collection(palace, "drawers") # create=False, row missing col.count() # after col = backend.get_collection(palace, "drawers", create=True) col.count()
Defensive patterns
Strategy: try-catch
Validate before calling
def collection_exists(backend, palace, name) -> bool:
try:
backend.get_collection(palace, name)
return True
except CollectionNotInitializedError:
return False Try / catch
try:
col.count()
except CollectionNotInitializedError:
col = backend.get_collection(palace, col._collection_name, create=True)
col.count() Prevention
- Fetch collection handles freshly per task instead of storing them long-term.
- Log the palace path alongside collection operations to catch path-switch bugs.
- After restore/backup operations, drop all cached handles and reopen.
When it happens
Trigger: Using a collection handle obtained with `create=True` from one palace path against a different/empty db (path confusion); the collection was deleted by `delete_collection` while a stale handle is still used; the db file was replaced/restored from backup after the handle was created; concurrent creation raced and the row rolled back.
Common situations: Switching PALACE_PATH or working directory between get_collection and later operations; tests sharing module-scoped handles against per-test fresh dbs; restoring a palace from a snapshot while the process holds old collection objects.
Related errors
- SQLiteExactCollection has been closed
- {palace_path}
- MilvusCollection has been closed
- PgVectorBackend has been closed
- QdrantCollection has been closed
AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15).
Data as JSON: /api/errors/fbc54afd59a11131.
Report an issue: GitHub.