{"record":{"id":"2df0239548c28d47","repo":"jd-opensource/joyagent-jdgenie","slug":"error-2df023","errorCode":null,"errorMessage":"向量生成失败！","messagePattern":"向量生成失败！","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/service/VectorService.java","lineNumber":80,"sourceCode":"            log.error(\"vectorRecall error: req:{}\", JSONObject.toJSONString(req), e);\n            if (future != null) {\n                try {\n                    future.cancel(true);\n                } catch (Exception e1) {\n                    log.error(e1.getMessage(), e1);\n                }\n            }\n        }\n\n        return new ArrayList<>();\n    }\n\n    private List<Map<String, Object>> recall(VectorRecallReq req) {\n        try {\n            List<Float> vector = embeddingService.getVector(req.getQuery());\n            if (CollectionUtils.isEmpty(vector)) {\n                log.error(\"vectorRecall error: vector is empty, req:{}\", JSONObject.toJSONString(req));\n                throw new RuntimeException(\"向量生成失败！\");\n            }\n\n            Points.Filter filter = null;\n            if (Objects.nonNull(req.getKeywordFilterMap()) && !req.getKeywordFilterMap().isEmpty()) {\n                Points.Filter.Builder filterBuilder = Points.Filter.newBuilder();\n                req.getKeywordFilterMap().forEach((k, v) -> {\n                    if (v instanceof String) {\n                        filterBuilder.addMust(matchKeyword(k, (String) v));\n                    } else if (v instanceof Long) {\n                        filterBuilder.addMust(match(k, (long) v));\n                    } else if (v instanceof Integer) {\n                        filterBuilder.addMust(match(k, (int) v));\n                    } else if (v instanceof Boolean) {\n                        filterBuilder.addMust(match(k, (boolean) v));\n                    } else if (v instanceof List) {\n                        List<Object> list = (List<Object>) v;\n                        if (CollectionUtils.isNotEmpty(list)) {\n                            Object type = list.get(0);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/service/VectorService.java#L62-L98","documentation":"VectorService.recall throws this when embeddingService.getVector(query) returns a null or empty vector, meaning the embedding model/service failed to produce an embedding for the query text. The recall cannot proceed without a vector to search with.","triggerScenarios":"getVector returns empty because the embedding HTTP call failed or returned an unexpected body; query text is in a language/format the model rejects; embedding service credentials/URL misconfigured so the empty-vector branch is hit.","commonSituations":"Embedding service down or returning 4xx/5xx consumed as empty result; embedding API key expired; query exceeds model token limit and service silently returns nothing; model name changed after an upgrade.","solutions":["Check embedding service health and its logs for the failing request (URL, auth, payload).","Validate embeddingService config (endpoint URL, API key, model name) is correct for the environment.","Inspect getVector: it likely swallows errors and returns empty — make it throw with the upstream status/body so the root cause is visible.","Add retry with backoff for transient embedding-service failures before giving up.","Truncate/validate query length against the embedding model's token limit."],"exampleFix":"// before\nList<Float> vector = embeddingService.getVector(req.getQuery());\nif (CollectionUtils.isEmpty(vector)) {\n    throw new RuntimeException(\"向量生成失败！\");\n}\n// after\nList<Float> vector = embeddingService.getVector(req.getQuery());\nif (CollectionUtils.isEmpty(vector)) {\n    log.error(\"embedding failed, queryLen={}, req={}\", req.getQuery().length(), JSONObject.toJSONString(req));\n    throw new RuntimeException(\"向量生成失败！ query=\" + req.getQuery());\n}","handlingStrategy":"retry","validationCode":"// java (caller): sanity-check embedding availability indirectly\n// ensure query is non-blank and within token limits before calling\nif (StringUtils.isBlank(query) || query.length() > MAX_QUERY_LEN) {\n    throw new IllegalArgumentException(\"query empty or too long for embedding model\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return vectorService.vectorRecall(req);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"向量生成失败\")) {\n        // embedding service degraded: retry once, then fall back to keyword search\n        return fallbackKeywordSearch(req.getQuery());\n    }\n    throw e;\n}","preventionTips":["Health-check the embedding service and alert on empty-vector rates.","Validate embedding endpoint, API key, and model name per environment.","Truncate queries to the model's token limit before embedding.","Make getVector surface upstream HTTP errors rather than returning empty."],"tags":["embedding","vector-search","upstream-service","java"],"backgroundTag":"upstream-api-error","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"}