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

  1. Re-obtain the collection with `create=True` after the underlying db changes: `col = backend.get_collection(palace, name, create=True)`.
  2. Verify you are pointing at the same palace path that the handle was created from (print both paths).
  3. Do not reuse collection handles after `delete_collection`; fetch a fresh one.
  4. 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

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


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/fbc54afd59a11131. Report an issue: GitHub.