MemPalace/mempalace · error · BackendMismatchError

pgvector marker is missing target metadata

Error message

pgvector marker is missing target metadata

What it means

A valid pgvector marker must carry a "pgvector" object describing its target (DSN/namespace). If that object is missing or not a dict, _validate_marker_target raises BackendMismatchError because the backend cannot verify the palace is bound to the expected database — an incomplete anchor is treated as a mismatch rather than ignored.

Source

Thrown at mempalace/backends/pgvector.py:1431

        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
        os.makedirs(palace.local_path, exist_ok=True)
        try:
            os.chmod(palace.local_path, 0o700)
        except (OSError, NotImplementedError):

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Delete the incomplete marker and reopen the palace with create=True to rewrite it from the current configuration.
  2. If you must hand-edit, restore the full structure: {"backend": "pgvector", "pgvector": {"dsn": ..., "namespace": ...}}.
  3. Otherwise start a fresh palace directory and re-ingest.

Example fix

# before
# marker: {"backend": "pgvector"}  (no "pgvector" target object)
col = palace.get_collection("notes")

# after
os.remove(marker_path)
col = palace.get_collection("notes", create=True)  # rewrites full marker
Defensive patterns

Strategy: try-catch

Validate before calling

marker = json.load(open(marker_path, encoding="utf-8"))
if not isinstance(marker.get("pgvector"), dict):
    raise RuntimeError("incomplete pgvector marker; recreate palace or re-anchor with create=True")

Type guard

def has_pgvector_target(marker: dict) -> bool:
    return isinstance(marker.get("pgvector"), dict)

Try / catch

try:
    palace.get_collection("notes")
except BackendMismatchError as e:
    if "missing target metadata" in str(e):
        os.remove(marker_path)
        palace.get_collection("notes", create=True)

Prevention

When it happens

Trigger: Marker JSON like {"backend": "pgvector"} with no "pgvector" key, or "pgvector": "host:5432" (a string instead of an object); caused by manual editing, an older-format marker, or corrupted writes.

Common situations: Upgrading from an older MemPalace version whose marker format lacked the target block; hand-crafting a marker to 'fix' another error; partial file writes.

Related errors


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