MemPalace/mempalace · error · BackendMismatchError

pgvector marker is unreadable: {marker_path}

Error message

pgvector marker is unreadable: {marker_path}

What it means

The pgvector backend stores a marker JSON file inside the local palace directory to pin the palace to a specific database (DSN + namespace). When that file exists but cannot be read (I/O error) or does not parse as JSON, the backend raises BackendMismatchError rather than guessing — a corrupt anchor is treated as a potential wrong-database situation. The original OSError/JSONDecodeError is chained as __cause__.

Source

Thrown at mempalace/backends/pgvector.py:1419

                "table_prefix": self._table_prefix(palace=palace, config=config),
            }
        )
        return target

    def _marker_exists(self, palace: PalaceRef) -> bool:
        return bool(palace.local_path and os.path.isfile(self._marker_path(palace.local_path)))

    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(

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Inspect the marker file (path is in the message) for truncation or corruption.
  2. If the correct DSN/namespace is known, delete the corrupt marker and reopen with create=True so a fresh marker is written.
  3. Otherwise start a fresh palace directory and re-ingest.

Example fix

# before
# marker file is corrupt JSON -> BackendMismatchError on open
col = palace.get_collection("notes")

# after
# remove corrupt marker, then reopen with create to rewrite it
os.remove(marker_path)
col = palace.get_collection("notes", create=True)
Defensive patterns

Strategy: try-catch

Validate before calling

import json, os
marker = backend._marker_path(palace.local_path)
if os.path.isfile(marker):
    try:
        json.load(open(marker, encoding="utf-8"))
    except (OSError, json.JSONDecodeError):
        os.remove(marker)  # only if you can safely re-anchor with create=True

Try / catch

try:
    col = palace.get_collection("notes", create=True)
except BackendMismatchError as e:
    if "unreadable" in str(e):
        # re-anchor: remove corrupt marker and reopen with create=True
        raise

Prevention

When it happens

Trigger: Truncation of the marker file by a crash mid-write, disk issues, manual editing that breaks JSON, or a non-UTF-8 file at <palace>/.pgvector marker path; any get_collection()/open on that palace then fails.

Common situations: Process killed during _write_marker; syncing the palace dir with a tool that mangles small JSON files; restoring a palace from a partial backup.

Related errors


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