{"record":{"id":"fbd0606360abc408","repo":"jd-opensource/joyagent-jdgenie","slug":"error-fbd060","errorCode":null,"errorMessage":"元数据为空！","messagePattern":"元数据为空！","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/service/QdrantService.java","lineNumber":243,"sourceCode":"                    .putAllPayload(maps.get(i))\n                    .build();\n            pointStructList.add(pointStruct);\n        }\n\n        return client.upsertAsync(collectionName, pointStructList).get();\n    }\n\n    public Points.UpdateResult upsertVector(String collectionName, List<Float> vector, Map<String, JsonWithInt.Value> payload) throws ExecutionException, InterruptedException {\n        if (StringUtils.isBlank(collectionName)) {\n            throw new RuntimeException(\"集合名为空！\");\n        }\n\n        if (Objects.isNull(vector)) {\n            throw new RuntimeException(\"向量为空！\");\n        }\n\n        if (Objects.isNull(payload)) {\n            throw new RuntimeException(\"元数据为空！\");\n        }\n\n\n        List<Points.PointStruct> pointStructList = new ArrayList<>();\n\n        Points.PointStruct pointStruct = Points.PointStruct.newBuilder()\n                .setId(id(UUID.randomUUID()))\n                .setVectors(vectors(vector))\n                .putAllPayload(payload)\n                .build();\n        pointStructList.add(pointStruct);\n\n        return client.upsertAsync(collectionName, pointStructList).get();\n    }\n\n    private List<Map<String, JsonWithInt.Value>> transPayloadMap(List<Map<String, Object>> payloads) {\n        List<Map<String, JsonWithInt.Value>> mapList = new ArrayList<>();\n","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/service/QdrantService.java#L225-L261","documentation":"Parameter validation in QdrantService.upsertVector: the payload (metadata map) for the single point is null, so the upsert would create a point with no metadata. This is the last of the three sequential guards (collection name, vector, payload) that validate arguments before issuing the upsertAsync call; fires when callers omit the metadata map for the vector being stored.","triggerScenarios":"Calling upsertVector(collection, vector, null), e.g. when metadata construction was skipped, a lookup for the document's metadata returned null, or the payload field in the source record was never populated.","commonSituations":"Document metadata missing in the source system; join with a metadata table returning null; nullable DTO field passed directly; refactoring that removed a default-payload builder.","solutions":["Pass an empty ImmutableMap/HashMap instead of null when no metadata exists.","Fix the metadata source so a payload map is always produced alongside the vector.","Guard the call site: default null payloads to Collections.emptyMap() before invoking.","Make the metadata builder return an empty map rather than null on missing data."],"exampleFix":"// before\nservice.upsertVector(collection, vector, metadata); // metadata is null\n// after\nMap<String, JsonWithInt.Value> payload =\n        metadata != null ? metadata : Collections.emptyMap();\nservice.upsertVector(collection, vector, payload);","handlingStrategy":"validation","validationCode":"if (payload == null) {\n    throw new IllegalArgumentException(\"payload map must not be null before upsertVector\");\n}","typeGuard":"static boolean hasPayload(Map<String, ?> payload) {\n    return payload != null;\n}","tryCatchPattern":"try {\n    service.upsertVector(collection, vector, payload);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"元数据为空\")) {\n        log.error(\"Null payload for single upsert on collection {}\", collection, e);\n    }\n    throw e;\n}","preventionTips":["Default missing metadata to Collections.emptyMap() instead of null","Ensure metadata builders never return null; return an empty map on missing data","Construct vector and payload together so one cannot exist without the other"],"tags":["validation","qdrant","null-argument","java"],"backgroundTag":"null-argument","analyzedSha":"2417e0b8b636d941ad5fb14c59b20dddfef5375d","analyzedAt":"2026-09-08T11:28:19.414Z","contentChangedAt":"2026-09-08T11:28:19.414Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}