jd-opensource/joyagent-jdgenie · error · RuntimeException

vectorIdList is null!

Error message

vectorIdList is null!

What it means

deleteVector validates its inputs before deleting points from the Qdrant collection. If vectorIdList is null or empty (CollectionUtils.isEmpty), it fails fast with this RuntimeException instead of issuing a pointless or invalid delete call to Qdrant.

Solutions

  1. Ensure the caller populates vectorIdList with valid UUID strings before calling deleteVector
  2. Guard the call site: skip deletion when the list is null or empty
  3. Log and no-op instead of throwing when an empty delete is acceptable
  4. Pass a Qdrant Filter-based deleteVector overload if you intend a bulk delete by criteria

Example fix

// before
vectorService.deleteVector("my-collection", ids);
// after
if (ids != null && !ids.isEmpty()) {
    vectorService.deleteVector("my-collection", ids);
}
Defensive patterns

Strategy: validation

Validate before calling

if (vectorIdList == null || vectorIdList.isEmpty()) {
    throw new IllegalArgumentException("vectorIdList must be non-empty");
}
vectorIdList.forEach(id -> UUID.fromString(id)); // validate UUID format too
vectorService.deleteVector(collectionName, vectorIdList);

Try / catch

try {
    vectorService.deleteVector(collectionName, vectorIdList);
} catch (RuntimeException e) {
    log.warn("vector delete skipped: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling VectorService.deleteVector(collectionName, vectorIdList) with a null list or an empty list of vector IDs; also when an upstream caller passes an unpopulated ID list collected from an empty query result.

Common situations: Batch cleanup jobs where the ID list is built by filtering/collecting and yields zero matches; callers that never check a lookup returned no IDs before attempting deletion.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/3d154f99e614dcd3. Report an issue: GitHub.

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/service/VectorService.java:156

                    return data.getUuid();
                }
                return UUID.randomUUID().toString();
            }).collect(Collectors.toList());
            List<Map<String, Object>> payloads = vectorSaveReq.getDataList().stream().map(VectorSaveReq.VectorData::getPayloads).collect(Collectors.toList());
            qdrantService.upsertVectorsPayloadTrans(vectorSaveReq.getCollectionName(), idList, vector, payloads);
            return true;
        } catch (Exception e) {
            log.error("saveVector error: req:{}", JSONObject.toJSONString(vectorSaveReq), e);
            return false;
        }
    }

    public Boolean deleteVector(String collectionName, List<String> vectorIdList) {
        if (StringUtils.isBlank(collectionName)) {
            throw new RuntimeException("collectionName is null!");
        }
        if (CollectionUtils.isEmpty(vectorIdList)) {
            throw new RuntimeException("vectorIdList is null!");
        }

        try {
            List<Points.PointId> pointIds = vectorIdList.stream().map(vId -> PointIdFactory.id(UUID.fromString(vId))).collect(Collectors.toList());
            qdrantService.deletePointsSync(collectionName, pointIds);
            return true;
        } catch (Exception e) {
            log.error("vector delete failed, collectionName:{}", collectionName, e);
            return false;
        }
    }

    public Boolean deleteVector(String collectionName, Points.Filter filter) {
        if (StringUtils.isBlank(collectionName)) {
            throw new RuntimeException("collectionName is null!");
        }
        if (filter == null) {
            throw new RuntimeException("filter is null!");

View on GitHub (pinned to 2417e0b8b6)