{"record":{"id":"ef605e15e4616731","repo":"microsoft/semantic-kernel","slug":"upsert-failed-ef605e","errorCode":null,"errorMessage":"Upsert failed","messagePattern":"Upsert failed","errorType":"exception","errorClass":"ServiceResponseException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/memory_stores/qdrant/qdrant_memory_store.py","lineNumber":100,"sourceCode":"    @override\n    async def does_collection_exist(self, collection_name: str) -> bool:\n        return self._qdrantclient.collection_exists(collection_name=collection_name)\n\n    @override\n    async def upsert(self, collection_name: str, record: MemoryRecord) -> str:\n        data_to_upsert = await self._convert_from_memory_record(\n            collection_name=collection_name,\n            record=record,\n        )\n\n        result = self._qdrantclient.upsert(\n            collection_name=collection_name,\n            points=[data_to_upsert],\n        )\n\n        if result.status == qdrant_models.UpdateStatus.COMPLETED:\n            return data_to_upsert.id\n        raise ServiceResponseException(\"Upsert failed\")\n\n    @override\n    async def upsert_batch(self, collection_name: str, records: list[MemoryRecord]) -> list[str]:\n        tasks = []\n        for record in records:\n            tasks.append(\n                self._convert_from_memory_record(\n                    collection_name=collection_name,\n                    record=record,\n                )\n            )\n\n        data_to_upsert = await asyncio.gather(*tasks)\n\n        result = self._qdrantclient.upsert(\n            collection_name=collection_name,\n            points=data_to_upsert,\n        )","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/memory_stores/qdrant/qdrant_memory_store.py#L82-L118","documentation":"Raised by QdrantMemoryStore.upsert() when the Qdrant client returns a result whose status is not UpdateStatus.COMPLETED. It is a ServiceResponseException; the upsert may have been acknowledged but not confirmed within the wait window. Note upsert() does not check collection existence first, so an absent collection usually surfaces as a client error before reaching this line.","triggerScenarios":"Calling `await store.upsert(collection_name, record)` where self._qdrantclient.upsert(...) returns status ACKNOWLEDGED (or any non-COMPLETED value), e.g. when the client is configured with wait=False or the operation times out before confirmation.","commonSituations":"QdrantClient created without wait=True semantics; heavy load causing the operation to be acknowledged but not completed within the timeout; transient network issues; very large point payloads.","solutions":["Retry the upsert with exponential backoff for transient non-COMPLETED statuses.","Configure the QdrantClient for synchronous confirmation (so status reflects actual completion).","Reduce batch/point size or warm the collection before bulk upserts.","Catch ServiceResponseException, log result.status, and decide retry vs fail."],"exampleFix":"// before\nkey = await store.upsert('mycol', record)\n// after\nfrom semantic_kernel.exceptions import ServiceResponseException\nfor attempt in range(3):\n    try:\n        key = await store.upsert('mycol', record)\n        break\n    except ServiceResponseException:\n        if attempt == 2: raise\n        await asyncio.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions import ServiceResponseException\nfor attempt in range(3):\n    try:\n        key = await store.upsert(collection_name, record)\n        break\n    except ServiceResponseException:\n        if attempt == 2:\n            raise\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Configure QdrantClient to wait for confirmation so a non-COMPLETED status is meaningful.","Retry transient non-COMPLETED statuses with exponential backoff.","Log the result.status value when this fires to distinguish timeout vs rejection."],"tags":["qdrant","memory-store","upsert","service-response-exception","retry"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}