{"record":{"id":"8b8c9c58d8a121a5","repo":"apache/seatunnel","slug":"upsert-failed","errorCode":null,"errorMessage":"Upsert failed","messagePattern":"Upsert failed","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-qdrant/src/main/java/org/apache/seatunnel/connectors/seatunnel/qdrant/sink/QdrantBatchWriter.java","lineNumber":138,"sourceCode":"        if (!point.hasId()) {\n            point.setId(id(UUID.randomUUID()));\n        }\n\n        point.setVectors(Points.Vectors.newBuilder().setVectors(namedVectors).build());\n        return point.build();\n    }\n\n    private void upsert() {\n        try {\n            qdrantClient\n                    .upsertAsync(\n                            Points.UpsertPoints.newBuilder()\n                                    .setCollectionName(collectionName)\n                                    .addAllPoints(qdrantDataCache)\n                                    .build())\n                    .get();\n        } catch (InterruptedException | ExecutionException e) {\n            throw new RuntimeException(\"Upsert failed\", e);\n        }\n    }\n\n    public static Points.PointId pointId(SeaTunnelDataType<?> fieldType, Object value) {\n        SqlType sqlType = fieldType.getSqlType();\n        switch (sqlType) {\n            case INT:\n                return id(Integer.parseInt(value.toString()));\n            case STRING:\n                return id(UUID.fromString(value.toString()));\n            default:\n                throw new QdrantConnectorException(\n                        CommonErrorCode.UNSUPPORTED_DATA_TYPE,\n                        \"Unexpected value type for point ID: \" + sqlType.name());\n        }\n    }\n\n    public static JsonWithInt.Value buildPayload(SeaTunnelDataType<?> fieldType, Object value) {","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-qdrant/src/main/java/org/apache/seatunnel/connectors/seatunnel/qdrant/sink/QdrantBatchWriter.java#L120-L156","documentation":"QdrantBatchWriter.upsert submits a batched Points.UpsertPoints gRPC call asynchronously and blocks on the future's get(). If the future is interrupted or completes exceptionally, the writer wraps the cause in a RuntimeException('Upsert failed'). The actual reason (timeout, collection missing, connection failure, unauthenticated) is always in the cause chain.","triggerScenarios":"flush() calls upsert(); the gRPC upsert future throws ExecutionException (server error, connection loss, deadline exceeded) or the waiting thread is interrupted.","commonSituations":"Qdrant collection does not exist or was deleted mid-job; Qdrant host/port wrong or unreachable from worker nodes; batch too large exceeding gRPC message limits; auth/API key mismatch; network timeouts under load.","solutions":["Inspect the wrapped cause for the concrete gRPC status (NOT_FOUND, UNAVAILABLE, DEADLINE_EXCEEDED, etc.)","Verify the collection name exists in Qdrant (create it or enable auto-creation in the connector config)","Check network connectivity and Qdrant URL/credentials from all SeaTunnel worker nodes","Reduce batch_size to stay under gRPC max message size","Retry the job if the cause was a transient interruption or brief unavailability"],"exampleFix":"// before\n} catch (InterruptedException | ExecutionException e) {\n    throw new RuntimeException(\"Upsert failed\", e);\n}\n// after\n} catch (InterruptedException e) {\n    Thread.currentThread().interrupt();\n    throw new RuntimeException(\"Upsert failed (interrupted)\", e);\n} catch (ExecutionException e) {\n    LOG.error(\"Qdrant upsert failed; check collection existence, connectivity and batch size\", e);\n    throw new RuntimeException(\"Upsert failed\", e);\n}","handlingStrategy":"retry","validationCode":"// pre-flight: collection must exist and be reachable\nboolean ok = client.collectionExistsAsync(collectionName).get(5, TimeUnit.SECONDS);\nif (!ok) throw new IllegalStateException(\"Qdrant collection missing: \" + collectionName);","typeGuard":null,"tryCatchPattern":"try {\n    writer.flush(); // triggers upsert\n} catch (RuntimeException e) {\n    if (\"Upsert failed\".equals(e.getMessage())) {\n        Throwable cause = e.getCause();\n        if (cause instanceof InterruptedException) {\n            Thread.currentThread().interrupt();\n        }\n        // inspect gRPC status in cause; retry on transient UNAVAILABLE/DEADLINE_EXCEEDED\n    } else throw e;\n}","preventionTips":["Create the Qdrant collection before running the job or enable auto-creation","Validate host/port/API key connectivity from all worker nodes pre-job","Keep batch sizes under the gRPC max message size (default 4MB)","Use modest write concurrency to avoid broker-side overload and timeouts"],"tags":["qdrant","grpc","vector-database","write-failed"],"backgroundTag":"database-write-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}