MemPalace/mempalace · error · UnsupportedMaintenanceKindError

backend does not support maintenance kind {kind!r}

Error message

backend does not support maintenance kind {kind!r}

What it means

A FileNotFoundError raised by the strict path of the FTS5/VACUUM rebuild helper: the recovered palace directory exists but contains no chroma.sqlite3. SQLite recovery passes strict=True because its bulk upserts must not be declared successful until the derived index is rebuilt and quick_check passes, so a missing database file is fatal rather than a warning.

Source

Thrown at mempalace/backends/base.py:535

        """Return a structured snapshot of this collection's maintenance state.

        Free-form per backend (e.g. row count, whether a vector index exists,
        last-analyze age). Used by benchmark harnesses to record state
        alongside each latency/recall measurement so an un-analyzed store is
        not compared against a settled one (RFC 001). Defaults to empty.
        """
        return {}

    def run_maintenance(self, kind: str) -> "MaintenanceResult":
        """Run a maintenance ``kind`` and return an observable result (RFC 001).

        Backends advertise supported kinds in ``BaseBackend.maintenance_kinds``
        and override this. The default supports nothing, so every kind raises
        :class:`UnsupportedMaintenanceKindError`. Implementations MUST serialize
        concurrent same-kind runs and report ``already_running`` rather than
        stacking the work.
        """
        raise UnsupportedMaintenanceKindError(f"backend does not support maintenance kind {kind!r}")

    def lexical_search(
        self,
        *,
        query: str,
        n_results: int = 10,
        where: Optional[dict] = None,
    ) -> LexicalResult:
        raise UnsupportedCapabilityError("backend does not support lexical_search")

    def update(
        self,
        *,
        ids: list[str],
        documents: Optional[list[str]] = None,
        metadatas: Optional[list[dict]] = None,
        embeddings: Optional[list[list[float]]] = None,
    ) -> None:

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Check that the source palace actually contains chroma.sqlite3 at its root.
  2. Re-copy the source palace in full (including chroma.sqlite3) and re-run the recovery.
  3. If the source genuinely lacks the DB, re-mine from original source files instead of recovering.

Example fix

import os
src_db = os.path.join(source_palace, 'chroma.sqlite3')
assert os.path.isfile(src_db), f'missing {src_db}; recovery will fail strict check'
Defensive patterns

Strategy: validation

Validate before calling

import os
assert os.path.isfile(os.path.join(dest_palace, 'chroma.sqlite3')), \
    'recovered palace missing chroma.sqlite3; strict cleanup will fail'

Try / catch

try:
    _vacuum_and_rebuild_fts5(dest_palace, strict=True)
except FileNotFoundError:
    # re-copy the SQLite DB from source, then retry cleanup

Prevention

When it happens

Trigger: The post-recovery cleanup (_vacuum_and_rebuild_fts5 with strict=True) runs on a dest_palace directory that lacks chroma.sqlite3 — e.g. the recovery copy step failed to copy the database, or the source palace never had one.

Common situations: Recovering a palace from a partial copy, a backup that excluded chroma.sqlite3, or a palace directory that only contains segment folders without the central SQLite DB.

Related errors


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