{"record":{"id":"c45a2b4435ce1870","repo":"jd-opensource/joyagent-jdgenie","slug":"datalist-is-null","errorCode":null,"errorMessage":"dataList is null!","messagePattern":"dataList is null!","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/service/VectorService.java","lineNumber":131,"sourceCode":"                Map<String, JsonWithInt.Value> payloadMap = p.getPayloadMap();\n                payloadMap.forEach((k, v) -> hashMap.put(k, v.getStringValue()));\n                hashMap.put(\"score\", p.getScore());\n                hashMap.put(\"_id\", p.getId().getUuid());\n                return hashMap;\n            }).collect(Collectors.toList());\n        } catch (Exception e) {\n            log.error(\"vectorRecall error: req:{}\", JSONObject.toJSONString(req), e);\n            throw new RuntimeException(e);\n        }\n    }\n\n    public Boolean saveVector(VectorSaveReq vectorSaveReq) {\n        try {\n            if (StringUtils.isBlank(vectorSaveReq.getCollectionName())) {\n                throw new RuntimeException(\"collectionName is null!\");\n            }\n            if (CollectionUtils.isEmpty(vectorSaveReq.getDataList())) {\n                throw new RuntimeException(\"dataList is null!\");\n            }\n\n            List<String> textList = vectorSaveReq.getDataList().stream().map(VectorSaveReq.VectorData::getEmbeddingText).collect(Collectors.toList());\n            List<List<Float>> vector = embeddingService.getVectorBatch(textList);\n            List<String> idList = vectorSaveReq.getDataList().stream().map(data -> {\n                if (StringUtils.isNotBlank(data.getUuid()) && isUuid(data.getUuid())) {\n                    return data.getUuid();\n                }\n                return UUID.randomUUID().toString();\n            }).collect(Collectors.toList());\n            List<Map<String, Object>> payloads = vectorSaveReq.getDataList().stream().map(VectorSaveReq.VectorData::getPayloads).collect(Collectors.toList());\n            qdrantService.upsertVectorsPayloadTrans(vectorSaveReq.getCollectionName(), idList, vector, payloads);\n            return true;\n        } catch (Exception e) {\n            log.error(\"saveVector error: req:{}\", JSONObject.toJSONString(vectorSaveReq), e);\n            return false;\n        }\n    }","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/service/VectorService.java#L113-L149","documentation":"Validation in VectorService.saveVector: the dataList field of the VectorSaveReq (the vectors/metadata to persist) is null, so there is nothing to save. The method wraps its work in a broad try-catch that logs and rethrows as RuntimeException, so this input check is the fast-fail path before any Qdrant interaction; fires when callers submit a save request with an absent or empty data list.","triggerScenarios":"Calling saveVector with dataList == null or an empty list — typically an upstream batch/transform step produced zero records (e.g., source query returned nothing) and the result was passed through unchanged.","commonSituations":"Upstream data extraction returned no rows for the sync window; a filter step removed all items before save; caller misuses the API assuming saveVector handles empty batches as a no-op.","solutions":["Check dataList.size() > 0 at the caller before invoking saveVector and skip the call for empty batches.","Investigate why the upstream pipeline produced zero records (source query, filters).","If empty batches are legitimate, treat them as a no-op in the caller instead of an error.","Ensure each VectorData in dataList has a non-blank embeddingText, since blank texts will produce useless embeddings."],"exampleFix":"// before\nvectorService.saveVector(buildSaveReq(records)); // records may be empty\n// after\nList<VectorSaveReq.VectorData> items = toVectorData(records);\nif (items.isEmpty()) {\n    log.info(\"no records to save, skipping saveVector\");\n    return true;\n}\nvectorService.saveVector(buildSaveReq(items));","handlingStrategy":"validation","validationCode":"// java (caller)\nif (saveReq.getDataList() == null || saveReq.getDataList().isEmpty()) {\n    return true; // nothing to save\n}","typeGuard":"boolean canSave(VectorSaveReq req) {\n    return req != null && CollectionUtils.isNotEmpty(req.getDataList());\n}","tryCatchPattern":"try {\n    vectorService.saveVector(saveReq);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"dataList is null\")) {\n        log.warn(\"saveVector called with empty dataList — check upstream pipeline\");\n        return false;\n    }\n    throw e;\n}","preventionTips":["Treat empty batches as no-ops at the caller instead of calling saveVector.","Alert when sync pipelines produce zero records — that usually precedes this error.","Ensure each VectorData.embeddingText is non-blank before batching."],"tags":["validation","vector-store","java","empty-input"],"backgroundTag":"empty-required-field","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"}