{"record":{"id":"e7629d34d9df00b9","repo":"MemPalace/mempalace","slug":"qdrant-marker-does-not-identify-the-qdrant-backend","errorCode":null,"errorMessage":"qdrant marker does not identify the qdrant backend","messagePattern":"qdrant marker does not identify the qdrant backend","errorType":"exception","errorClass":"BackendMismatchError","httpStatus":null,"severity":"error","filePath":"mempalace/backends/qdrant.py","lineNumber":1245,"sourceCode":"    def _read_marker(self, palace: PalaceRef) -> Optional[dict]:\n        if not palace.local_path:\n            return None\n        marker_path = self._marker_path(palace.local_path)\n        if not os.path.isfile(marker_path):\n            return None\n        try:\n            with open(marker_path, encoding=\"utf-8\") as f:\n                marker = json.load(f)\n        except (OSError, json.JSONDecodeError) as exc:\n            raise BackendMismatchError(f\"qdrant marker is unreadable: {marker_path}\") from exc\n        return marker if isinstance(marker, dict) else {}\n\n    def _validate_marker_target(self, palace: PalaceRef, config: _QdrantConfig) -> None:\n        marker = self._read_marker(palace)\n        if marker is None:\n            return\n        if marker.get(\"backend\") != self.name:\n            raise BackendMismatchError(\"qdrant marker does not identify the qdrant backend\")\n        expected = self._marker_target(palace, config)\n        actual = marker.get(\"qdrant\")\n        if not isinstance(actual, dict):\n            raise BackendMismatchError(\"qdrant marker is missing remote target metadata\")\n        mismatched = [\n            key for key, expected_value in expected.items() if actual.get(key) != expected_value\n        ]\n        if mismatched:\n            details = \", \".join(mismatched)\n            raise BackendMismatchError(\n                \"qdrant marker remote target does not match current configuration \"\n                f\"({details}); keep MEMPALACE_QDRANT_URL and namespace consistent \"\n                \"or use a fresh palace directory\"\n            )\n\n    def _write_marker(self, palace: PalaceRef, config: _QdrantConfig) -> None:\n        if not palace.local_path:\n            return","sourceCodeStart":1227,"sourceCodeEnd":1263,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/backends/qdrant.py#L1227-L1263","documentation":"Raised during marker validation when the marker file parses but its \"backend\" field does not equal \"qdrant\". The marker exists to prevent one backend from operating on a palace created by another backend (e.g. chromadb artifacts opened via qdrant); a foreign or malformed marker aborts the open.","triggerScenarios":"Opening a palace directory via the qdrant backend when the marker was written by a different backend implementation, when the marker JSON was hand-edited, or when an old marker format lacked the backend field (marker.get(\"backend\") returns None).","commonSituations":"User switched MEMPALACE_BACKEND (or equivalent config) from chromadb to qdrant while reusing the same palace directory; marker file rewritten by a tool; palace directory created by a much older version of mempalace before markers carried a backend field.","solutions":["Check which backend the palace was created with (read the marker's backend field) and open the palace with that backend","If the palace should be migrated to qdrant, export data with the original backend and re-ingest into a fresh qdrant palace","If the marker is simply wrong/stale and no other backend's data exists, delete the marker and re-create with create=True"],"exampleFix":"// before\nbackend = get_backend(\"qdrant\")\ncol = backend.get_collection(palace, \"drawers\")  # marker says backend=chromadb\n// after\nbackend = get_backend(marker[\"backend\"])  # open with the owning backend\ncol = backend.get_collection(palace, \"drawers\")","handlingStrategy":"validation","validationCode":"import json\ndef owning_backend(palace_path: str, marker_name: str) -> str | None:\n    try:\n        with open(os.path.join(palace_path, marker_name), encoding=\"utf-8\") as f:\n            return json.load(f).get(\"backend\")\n    except (OSError, json.JSONDecodeError):\n        return None\n# open palace only with owning_backend(palace_path, marker)","typeGuard":null,"tryCatchPattern":"from mempalace.backends.base import BackendMismatchError\ntry:\n    backend.get_collection(palace, name)\nexcept BackendMismatchError as e:\n    if \"does not identify\" in str(e):\n        switch_to_marker_backend()  # reopen with the backend named in the marker","preventionTips":["Pin one backend per palace directory; encode it in your config","Never switch backend env vars against an existing palace without migration"],"tags":["qdrant","marker","backend-mismatch"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}