MemPalace/mempalace · error · BackendMismatchError

pgvector marker does not identify the pgvector backend

Error message

pgvector marker does not identify the pgvector backend

What it means

The palace marker JSON must contain "backend": "pgvector" to prove it was created by this backend. If the backend field is absent or names a different backend (e.g. "chroma"), PgVectorBackend refuses to open the palace with BackendMismatchError — opening a ChromaDB palace against pgvector would silently strand the existing data.

Source

Thrown at mempalace/backends/pgvector.py:1427

    def _read_marker(self, palace: PalaceRef) -> Optional[dict]:
        if not palace.local_path:
            return None
        marker_path = self._marker_path(palace.local_path)
        if not os.path.isfile(marker_path):
            return None
        try:
            with open(marker_path, encoding="utf-8") as f:
                marker = json.load(f)
        except (OSError, json.JSONDecodeError) as exc:
            raise BackendMismatchError(f"pgvector marker is unreadable: {marker_path}") from exc
        return marker if isinstance(marker, dict) else {}

    def _validate_marker_target(self, palace: PalaceRef, config: _PgVectorConfig) -> None:
        marker = self._read_marker(palace)
        if marker is None:
            return
        if marker.get("backend") != self.name:
            raise BackendMismatchError("pgvector marker does not identify the pgvector backend")
        expected = self._marker_target(palace, config)
        actual = marker.get("pgvector")
        if not isinstance(actual, dict):
            raise BackendMismatchError("pgvector marker is missing target metadata")
        mismatched = [
            key for key, expected_value in expected.items() if actual.get(key) != expected_value
        ]
        if mismatched:
            details = ", ".join(mismatched)
            raise BackendMismatchError(
                "pgvector marker target does not match current configuration "
                f"({details}); keep MEMPALACE_PGVECTOR_DSN and namespace consistent "
                "or use a fresh palace directory"
            )

    def _write_marker(self, palace: PalaceRef, config: _PgVectorConfig) -> None:
        if not palace.local_path:
            return

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Use a fresh palace directory when switching to the pgvector backend, then re-ingest.
  2. Or migrate properly via the exporter/migrate tooling rather than re-pointing the same directory.
  3. Set the backend configuration consistently (env/config) with the palace you are opening.

Example fix

# before
# same palace dir previously used with chroma
MEMPALACE_BACKEND=pgvector palace.get_collection("notes")

# after
# fresh dir for the new backend
MEMPALACE_BACKEND=pgvector MEMPALACE_PALACE=~/palaces/pg-new palace.get_collection("notes", create=True)
Defensive patterns

Strategy: validation

Validate before calling

marker = json.load(open(marker_path, encoding="utf-8"))
assert marker.get("backend") == "pgvector", f"palace belongs to {marker.get('backend')}"

Type guard

def marker_matches_backend(marker: dict, name: str) -> bool:
    return isinstance(marker, dict) and marker.get("backend") == name

Try / catch

try:
    col = palace.get_collection("notes")
except BackendMismatchError as e:
    if "does not identify" in str(e):
        raise RuntimeError("palace directory was created by another backend; use a fresh directory")

Prevention

When it happens

Trigger: Pointing the pgvector backend (MEMPALACE_PGVECTOR_DSN set / backend="pgvector") at a palace directory whose marker was written by the ChromaDB or qdrant backend; a hand-edited marker with a renamed backend field.

Common situations: Migrating between backends without a fresh palace directory; switching MEMPALACE_BACKEND env var while reusing the same local palace path.

Related errors


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