{"record":{"id":"d2f7edac41342c34","repo":"MemPalace/mempalace","slug":"sqlite-exact-does-not-support-maintenance-kind-ki","errorCode":null,"errorMessage":"sqlite_exact does not support maintenance kind {kind!r}","messagePattern":"sqlite_exact does not support maintenance kind (.+?)","errorType":"exception","errorClass":"UnsupportedMaintenanceKindError","httpStatus":null,"severity":"warning","filePath":"mempalace/backends/sqlite_exact.py","lineNumber":830,"sourceCode":"        except Exception:\n            rows = 0\n        # vector_index is null by design — exact cosine over every row, no ANN.\n        state = {\"row_count\": rows, \"vector_index\": None}\n        try:\n            with self._cursor() as cur:\n                page_count = cur.execute(\"PRAGMA page_count\").fetchone()\n                freelist = cur.execute(\"PRAGMA freelist_count\").fetchone()\n            state[\"page_count\"] = int(page_count[0]) if page_count else 0\n            state[\"freelist_pages\"] = int(freelist[0]) if freelist else 0\n        except Exception:\n            pass\n        return state\n\n    def run_maintenance(self, kind: str):\n        from .base import MaintenanceResult, UnsupportedMaintenanceKindError\n\n        if kind not in SQLiteExactBackend.maintenance_kinds:\n            raise UnsupportedMaintenanceKindError(\n                f\"sqlite_exact does not support maintenance kind {kind!r}\"\n            )\n        if kind == \"analyze\":\n            # Refresh planner stats. Concurrent runs serialize on the handle lock.\n            with self._cursor(write=True) as cur:\n                cur.execute(\"ANALYZE\")\n            return MaintenanceResult(kind=\"analyze\", status=\"ran\")\n\n        # compact → VACUUM. It cannot run inside a transaction, so flip the\n        # connection to autocommit for the duration. _write_lock takes the\n        # handle mutex before the palace lease so a waiting thread cannot\n        # retain stale process-reentrant ownership after another thread exits.\n        before = self.maintenance_state()\n        with self._write_lock():\n            conn = self._handle.conn\n            prev_isolation = conn.isolation_level\n            try:\n                conn.commit()","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/sqlite_exact.py#L812-L848","documentation":"Raised by `SQLiteExactBackend.run_maintenance(kind)` when `kind` is not in `SQLiteExactBackend.maintenance_kinds`. The backend implements only specific maintenance operations (`analyze` for planner stats, `compact` mapping to VACUUM); anything else — e.g. `reindex`, `vacuum-full`, `purge` — is rejected with this error rather than silently ignored.","triggerScenarios":"Calling `backend.run_maintenance(\"reindex\")` or any string not in the class-level `maintenance_kinds` set; passing a maintenance kind supported by the ChromaDB backend to sqlite_exact; typos like `\"analize\"` or `\"compact-full\"`.","commonSituations":"Generic maintenance tooling that probes several kinds across backends; config files listing maintenance jobs written for another backend; scripts copied from ChromaDB-based setups.","solutions":["Inspect `SQLiteExactBackend.maintenance_kinds` and call only those (typically `\"analyze\"` and `\"compact\"`).","Guard generic maintenance loops: `if kind in backend.maintenance_kinds: backend.run_maintenance(kind)`.","Catch UnsupportedMaintenanceKindError and skip that kind for this backend instead of failing the whole job."],"exampleFix":"# before\nbackend.run_maintenance(\"reindex\")  # unsupported\n\n# after\nif \"reindex\" in backend.maintenance_kinds:\n    backend.run_maintenance(\"reindex\")\nelse:\n    backend.run_maintenance(\"analyze\")","handlingStrategy":"try-catch","validationCode":"def supported_maintenance(backend, kind) -> bool:\n    return kind in getattr(backend, \"maintenance_kinds\", set())","typeGuard":null,"tryCatchPattern":"from mempalace.backends.base import UnsupportedMaintenanceKindError\n\nfor kind in jobs:\n    try:\n        backend.run_maintenance(kind)\n    except UnsupportedMaintenanceKindError:\n        logger.info(\"skipping %s on %s\", kind, type(backend).__name__)","preventionTips":["Drive maintenance from backend.maintenance_kinds instead of a hardcoded list.","Keep maintenance config per backend when supporting multiple backends.","Treat UnsupportedMaintenanceKindError as skip, not failure, in generic tooling."],"tags":["sqlite-exact","maintenance","vacuum","backend-api"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}