{"record":{"id":"a4100b1ecfdee3e1","repo":"MemPalace/mempalace","slug":"backend-does-not-support-lexical-search","errorCode":null,"errorMessage":"backend does not support lexical_search","messagePattern":"backend does not support lexical_search","errorType":"exception","errorClass":"UnsupportedCapabilityError","httpStatus":null,"severity":"critical","filePath":"mempalace/backends/base.py","lineNumber":544,"sourceCode":"    def run_maintenance(self, kind: str) -> \"MaintenanceResult\":\n        \"\"\"Run a maintenance ``kind`` and return an observable result (RFC 001).\n\n        Backends advertise supported kinds in ``BaseBackend.maintenance_kinds``\n        and override this. The default supports nothing, so every kind raises\n        :class:`UnsupportedMaintenanceKindError`. Implementations MUST serialize\n        concurrent same-kind runs and report ``already_running`` rather than\n        stacking the work.\n        \"\"\"\n        raise UnsupportedMaintenanceKindError(f\"backend does not support maintenance kind {kind!r}\")\n\n    def lexical_search(\n        self,\n        *,\n        query: str,\n        n_results: int = 10,\n        where: Optional[dict] = None,\n    ) -> LexicalResult:\n        raise UnsupportedCapabilityError(\"backend does not support lexical_search\")\n\n    def update(\n        self,\n        *,\n        ids: list[str],\n        documents: Optional[list[str]] = None,\n        metadatas: Optional[list[dict]] = None,\n        embeddings: Optional[list[list[float]]] = None,\n    ) -> None:\n        \"\"\"Default non-atomic update: get + merge + upsert.\n\n        Backends advertising ``supports_update`` MUST override with an atomic\n        single-round-trip implementation.\n        \"\"\"\n        if documents is None and metadatas is None and embeddings is None:\n            raise ValueError(\"update requires at least one of documents, metadatas, embeddings\")\n\n        n = len(ids)","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/base.py#L526-L562","documentation":"Raised as RebuildPartialError when a bulk upsert into the destination collection fails mid-way during a palace rebuild: some rows were written (the dest is now a partial palace) and the original was possibly archived. The error carries partial_counts, failed_collection, dest_palace, and archive_path so the operator knows exactly what state each copy is in.","triggerScenarios":"The upsert loop over extracted rows raises after {upserted} rows succeeded — disk full, embedding dimension mismatch, backend crash, or invalid metadata mid-stream.","commonSituations":"Rebuilding a large palace onto a nearly-full disk; chromadb rejecting a row with oversized/invalid metadata; the archive step moved the original aside so the user must recover from archive_path.","solutions":["Read the message: if an archive_path is given, the original palace is safe there; if not, the source is unchanged.","Delete the partial destination palace named in the message — it is incomplete and must not be used.","Fix the root cause ({exc!r}: disk space, bad metadata row, chromadb health).","Re-run the rebuild; with an archive, pass --source {archive_path} to rebuild from the archived original."],"exampleFix":"# Recovery flow after RebuildPartialError\nshutil.rmtree(dest_palace)            # remove partial copy\ncli.main(['rebuild', '--source', archive_path, ...])  # rebuild from archive","handlingStrategy":"try-catch","validationCode":"import shutil\nfree = shutil.disk_usage(dest_root).free\nif free < estimated_palace_size * 2:\n    raise SystemExit('insufficient disk space for rebuild + archive')","typeGuard":null,"tryCatchPattern":"try:\n    rebuild(...)\nexcept RebuildPartialError as e:\n    shutil.rmtree(e.dest_palace)          # partial copy is unusable\n    if e.archive_path:\n        rebuild(source=e.archive_path)    # original is safe in archive\n    else:\n        retry()                            # source was never touched","preventionTips":["Ensure ample free disk space before palace rebuilds.","Prefer rebuild modes that archive the original rather than in-place swaps.","Never treat a dest palace as good after a mid-rebuild failure."],"tags":["rebuild","partial-write","chromadb","data-loss","recovery"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}