jd-opensource/joyagent-jdgenie · error · RuntimeException
向量集合大小与元数据集合大小不一致,vectorSize:
Error message
向量集合大小与元数据集合大小不一致,vectorSize:{" + vectors.size() + "},payloadSize:{" + payloads.size() + "} What it means
upsertVectorsPayloadTrans enforces vectors.size() == payloads.size() so each vector is stored with exactly one payload by index. This guard fires on a length mismatch; the message includes both sizes.
Solutions
- Build vectors, payloads, and ids in a single iteration over the same source items so sizes cannot diverge.
- Use the vectorSize/payloadSize values in the message to identify which side is short and inspect that pipeline stage.
- Add a caller-side assertion with per-item diagnostics before calling the service.
- If items can legitimately lack metadata, pad with empty maps instead of omitting entries.
Example fix
// before
items.forEach(i -> vectors.add(embed(i)));
items.stream().filter(i -> i.hasMeta()).forEach(i -> payloads.add(toPayload(i))); // diverges
service.upsertVectorsPayloadTrans(collection, ids, vectors, payloads);
// after
for (Item i : items) {
vectors.add(embed(i));
payloads.add(toPayload(i)); // always add, empty map if no meta
}
service.upsertVectorsPayloadTrans(collection, ids, vectors, payloads); Defensive patterns
Strategy: validation
Validate before calling
if (vectors == null || payloads == null || vectors.size() != payloads.size()) {
throw new IllegalArgumentException("size mismatch before upsertVectorsPayloadTrans: vectors="
+ (vectors == null ? "null" : vectors.size()) + " payloads=" + (payloads == null ? "null" : payloads.size()));
} Type guard
static boolean areParallel(List<?> a, List<?> b) {
return a != null && b != null && a.size() == b.size();
} Try / catch
try {
service.upsertVectorsPayloadTrans(collection, ids, vectors, payloads);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("大小不一致")) {
log.error("Trans upsert parallel-list mismatch: {}", e.getMessage());
}
throw e;
} Prevention
- Iterate source items once, appending to ids, vectors, and payloads together
- Apply any filtering before building the lists, not to individual lists afterward
- Add a batch-integrity unit test covering partial-metadata items
When it happens
Trigger: Calling upsertVectorsPayloadTrans where the vector list and payload list have different element counts, e.g. 50 embeddings but 49 payloads because one document's metadata extraction was skipped.
Common situations: Per-item metadata generation failing for some items while embedding succeeded for all; chunking/merging bugs when splitting large documents; concurrent population of the lists; filtering applied to one list after both were built.
Related errors
AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08).
Data as JSON: /api/errors/c3202d82bd1fb55f.
Report an issue: GitHub.
Appendix: source
Thrown at genie-backend/src/main/java/com/jd/genie/service/QdrantService.java:215
public Points.UpdateResult upsertVectorsPayloadTrans(String collectionName, List<String> idList, List<List<Float>> vectors, List<Map<String, Object>> payloads) throws ExecutionException, InterruptedException {
if (StringUtils.isBlank(collectionName)) {
throw new RuntimeException("集合名为空!");
}
if (CollectionUtils.isEmpty(idList)) {
throw new RuntimeException("向量id集合为空!");
}
if (CollectionUtils.isEmpty(vectors)) {
throw new RuntimeException("向量集合为空!");
}
if (CollectionUtils.isEmpty(payloads)) {
throw new RuntimeException("元数据集合为空!");
}
if (vectors.size() != payloads.size()) {
throw new RuntimeException("向量集合大小与元数据集合大小不一致,vectorSize:" + vectors.size() + ",payloadSize:" + payloads.size());
}
List<Map<String, JsonWithInt.Value>> maps = transPayloadMap(payloads);
List<Points.PointStruct> pointStructList = new ArrayList<>();
for (int i = 0; i < vectors.size(); i++) {
Points.PointStruct pointStruct = Points.PointStruct.newBuilder()
.setId(id(UUID.fromString(idList.get(i))))
.setVectors(vectors(vectors.get(i)))
.putAllPayload(maps.get(i))
.build();
pointStructList.add(pointStruct);
}
return client.upsertAsync(collectionName, pointStructList).get();
}
public Points.UpdateResult upsertVector(String collectionName, List<Float> vector, Map<String, JsonWithInt.Value> payload) throws ExecutionException, InterruptedException {View on GitHub (pinned to 2417e0b8b6)