jd-opensource/joyagent-jdgenie · error · RuntimeException

nl2sql result is null

Error message

nl2sql result is null

What it means

nl2sqlQueryData validates the NL2SQLResult envelope before extracting data. If the parsed result is null or its code field is null, this RuntimeException is thrown — meaning the agent response could not be parsed into a valid NL2SQLResult (bad JSON shape or empty body).

Solutions

  1. Log the raw jsonResult and verify it parses to {code:200,...}
  2. Check that the agent endpoint is the NL2SQL API and not a generic error page
  3. Align NL2SQLResult field names with the agent's current response schema

Example fix

// before
if (nl2SQLResult == null || nl2SQLResult.getCode() == null) {
    throw new RuntimeException("nl2sql result is null");
}
// after
if (nl2SQLResult == null || nl2SQLResult.getCode() == null) {
    throw new RuntimeException("nl2sql result is null, traceId=" + request.getTraceId());
}
Defensive patterns

Strategy: type-guard

Validate before calling

NL2SQLResult r = JSONObject.parseObject(jsonResult, NL2SQLResult.class);
if (r == null || r.getCode() == null) {
    log.error("bad nl2sql response: {}", jsonResult);
    return;
}

Type guard

boolean isValidResult(NL2SQLResult r) {
    return r != null && r.getCode() != null;
}

Try / catch

try {
    List<ChatQueryData> data = nl2sqlQueryData(request, result);
} catch (RuntimeException e) {
    if ("nl2sql result is null".equals(e.getMessage())) {
        // inspect raw response / agent health
    }
    throw e;
}

Prevention

When it happens

Trigger: runNL2SQLSync/runNL2SQLSse call nl2sqlQueryData with nl2SQLResult==null (JSON parse of empty/garbage body) or with code==null (response JSON missing 'code').

Common situations: Agent returned an HTML error page or empty 200 body; version skew between agent response schema and NL2SQLResult fields; fastjson parse silently yielding null fields.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

        List<Pattern> patterns = codeList.stream()
                .distinct()
                .map(code -> Pattern.compile("(?i)(?<!`)\\b" + Pattern.quote(code) + "\\b(?!`)"))
                .toList();

        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();

View on GitHub (pinned to 2417e0b8b6)