jd-opensource/joyagent-jdgenie · error · RuntimeException

查询query为空!

Error message

查询query为空!

What it means

VectorService.vectorRecall throws this when VectorRecallReq.getQuery() is blank. Without a query string there is nothing to embed and search against in the vector store, so the request is rejected before any embedding or Qdrant call.

Solutions

  1. Guard caller-side: only invoke vectorRecall when the query text is non-blank after trimming.
  2. Fix the upstream step responsible for producing the query (user input handling, query rewrite).
  3. Provide a default/fallback behavior for empty user input instead of calling the vector service.
  4. Include the request id in the error for tracing empty-input occurrences.

Example fix

// before
String query = userInput.trim().toLowerCase();
req.setQuery(query);
vectorService.vectorRecall(req);
// after
String query = userInput == null ? "" : userInput.trim();
if (StringUtils.isBlank(query)) {
    return Collections.emptyList(); // skip vector recall for empty input
}
req.setQuery(query);
vectorService.vectorRecall(req);
Defensive patterns

Strategy: validation

Validate before calling

// java (caller)
if (StringUtils.isBlank(req.getQuery())) {
    return Collections.emptyList(); // skip recall entirely
}

Type guard

boolean hasQuery(VectorRecallReq req) {
    return req != null && StringUtils.isNotBlank(req.getQuery());
}

Try / catch

try {
    return vectorService.vectorRecall(req);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("查询query为空")) {
        log.warn("skipped vector recall: empty query");
        return Collections.emptyList();
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling vectorRecall with an empty/whitespace query — typically an empty user input passed straight through, or a pipeline step that should have filled the query field didn't run.

Common situations: User submitted an empty search box; an upstream NLU/rewriting step returned an empty string; trimming/normalization stripped the query to nothing before the call.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

    private QdrantService qdrantService;

    @Autowired
    public void setEmbeddingService(EmbeddingService embeddingService) {
        this.embeddingService = embeddingService;
    }

    @Autowired
    public void setQdrantService(QdrantService qdrantService) {
        this.qdrantService = qdrantService;
    }


    public List<Map<String, Object>> vectorRecall(VectorRecallReq req) {
        if (StringUtils.isBlank(req.getCollectionName())) {
            throw new RuntimeException("集合名称为空!");
        }
        if (StringUtils.isBlank(req.getQuery())) {
            throw new RuntimeException("查询query为空!");
        }

        CompletableFuture<List<Map<String, Object>>> future = null;
        try {
            future = CompletableFuture.supplyAsync(() -> recall(req));
            future.exceptionally(throwable -> null);
            List<Map<String, Object>> maps = future.get(req.getTimeout(), TimeUnit.MILLISECONDS);
            if (maps == null || maps.isEmpty()) {
                log.error("vectorRecall empty: req:{}", JSONObject.toJSONString(req));
                return new ArrayList<>();
            }
            return maps;
        } catch (Exception e) {
            log.error("vectorRecall error: req:{}", JSONObject.toJSONString(req), e);
            if (future != null) {
                try {
                    future.cancel(true);
                } catch (Exception e1) {

View on GitHub (pinned to 2417e0b8b6)