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
- Log the raw jsonResult and verify it parses to {code:200,...}
- Check that the agent endpoint is the NL2SQL API and not a generic error page
- 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
- Log raw agent responses for schema drift detection
- Validate agent response contract with integration tests
- Reject non-JSON (HTML) bodies early
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)