jd-opensource/joyagent-jdgenie · error · RuntimeException

nl2sql返回为空

Error message

nl2sql返回为空

What it means

Guard in Nl2SqlService.nl2sqlQueryData: before converting the NL2SQL service response into chat query data, the code verifies the response envelope exists and carries a code. A null result or null code means the upstream NL2SQL call produced no usable response object (transport failure, empty reply, deserialization gap). Both runNL2SQLSync and runNL2SQLSse funnel through here, so any caller of those entry points can surface this RuntimeException when the NL2SQL backend fails to return a well-formed response.

Solutions

  1. Verify the request query and selected models can actually produce SQL
  2. Log the full nl2SQLResult JSON to check the agent truly returned no data vs a field-name mismatch
  3. Tighten the prompt/query or choose models with proper schema metadata

Example fix

// before
if (CollectionUtils.isEmpty(nl2SQLResult.getData())) {
    throw new RuntimeException("nl2sql返回为空");
}
// after
if (CollectionUtils.isEmpty(nl2SQLResult.getData())) {
    throw new RuntimeException("nl2sql返回为空, query=" + request.getQuery());
}
Defensive patterns

Strategy: validation

Validate before calling

// after receiving result
if (result.getCode() == 200 && CollectionUtils.isEmpty(result.getData())) {
    log.warn("agent returned empty data for query: {}", request.getQuery());
}

Try / catch

try {
    return nl2sqlQueryData(request, result);
} catch (RuntimeException e) {
    if ("nl2sql返回为空".equals(e.getMessage())) {
        // degrade gracefully: return empty dataset instead of failing
        return Collections.emptyList();
    }
    throw e;
}

Prevention

When it happens

Trigger: NL2SQLResult.getCode()==200 and getData() is null or empty after a successful sync/SSE run.

Common situations: Query too vague so the agent generated nothing; model/table has no matching data; agent version returning results under a different JSON field so data deserializes empty.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/service/Nl2SqlService.java:104

        Matcher matcher;
        for (Pattern pattern : patterns) {
            matcher = pattern.matcher(input);
            if (matcher.find()) {
                return matcher.replaceFirst("`$0`");
            }
        }
        return input;
    }

    private List<ChatQueryData> nl2sqlQueryData(NL2SQLReq request, NL2SQLResult nl2SQLResult) throws Exception {
        if (nl2SQLResult == null || nl2SQLResult.getCode() == null) {
            throw new RuntimeException("nl2sql result is null");
        }
        if (nl2SQLResult.getCode() != 200) {
            throw new RuntimeException("nl2sql server return error:" + nl2SQLResult.getErr_msg());
        }
        if (CollectionUtils.isEmpty(nl2SQLResult.getData())) {
            throw new RuntimeException("nl2sql返回为空");
        }
        nl2SQLResult.setRootQuery(request.getQuery());
        for (NL2SQLResult.NL2SQLData nl2SQLData : nl2SQLResult.getData()) {
            String prettySql = replaceFirstMatchedOrThrow(nl2SQLData.getNl2sql(), request.getModelCodeList());
            nl2SQLData.setNl2sql(prettySql);
        }
        return queryData(request, nl2SQLResult);
    }

    public String getTableName(ChatModelInfoDto modelInfo) {
        if ("table".equalsIgnoreCase(modelInfo.getType())) {
            return modelInfo.getContent();
        } else if ("sql".equalsIgnoreCase(modelInfo.getType())) {
            return "(" + modelInfo.getContent() + ") t";
        } else {
            throw new RuntimeException("不支持的模型类型" + modelInfo.getType());
        }
    }

View on GitHub (pinned to 2417e0b8b6)