{"record":{"id":"f37389f71573d596","repo":"jd-opensource/joyagent-jdgenie","slug":"tablerag-result-is-null","errorCode":null,"errorMessage":"tableRag result is null","messagePattern":"tableRag result is null","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/service/TableRagService.java","lineNumber":45,"sourceCode":"    @Autowired\n    DataAgentConfig dataAgentConfig;\n\n    public List<ChatSchemaDto> tableRag(NL2SQLReq req) throws IOException {\n        if (!dataAgentConfig.getEsConfig().getEnable() && !dataAgentConfig.getQdrantConfig().getEnable()) {\n            log.info(\"{},{} 未开启向量和es，不进行tableRag\",req.getTraceId(),req.getRequestId());\n            return new ArrayList<>();\n        }\n        String res;\n        try {\n            res = OkHttpUtil.postJsonBody(dataAgentConfig.getAgentUrl() + TABLE_RAG_URL, null, JSONObject.toJSONString(req));\n        } catch (Exception e) {\n            log.warn(\"{},{} tableRag server error,retry:{}\",req.getTraceId(),req.getRequestId(), e.getMessage());\n            res = OkHttpUtil.postJsonBody(dataAgentConfig.getAgentUrl() + TABLE_RAG_URL, null, JSONObject.toJSONString(req));\n        }\n        log.info(\"{},{} tableRag result:{}\", req.getTraceId(),req.getRequestId(),res);\n        TableRagResult tableRagResult = JSONObject.parseObject(res, TableRagResult.class);\n        if (tableRagResult == null || tableRagResult.getCode() == null) {\n            throw new RuntimeException(\"tableRag result is null\");\n        }\n        if (tableRagResult.getCode() != 200) {\n            throw new RuntimeException(\"tableRag server return error\");\n        }\n        List<TableRagResult.TableRagData> data = tableRagResult.getData();\n        if (CollectionUtils.isEmpty(data)) {\n            throw new RuntimeException(\"tableRag result data is empty\");\n        }\n        return data.stream()\n                .filter(Objects::nonNull)\n                .map(TableRagResult.TableRagData::getSchemaList)\n                .filter(CollectionUtils::isNotEmpty)\n                .flatMap(Collection::stream)\n                .collect(Collectors.toList());\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":62,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/service/TableRagService.java#L27-L62","documentation":"TableRagService.tableRag throws this when the HTTP response from the data-agent TABLE_RAG_URL endpoint cannot be parsed into a TableRagResult or parses to an object with a null code. It indicates the remote table-RAG service returned an empty, malformed, or non-standard body, so no valid response envelope exists.","triggerScenarios":"OkHttpUtil.postJsonBody returns null or an empty/garbage string (network failure path, agent URL wrong, gateway returning HTML/empty body), making JSONObject.parseObject(res, TableRagResult.class) yield null or an object without code.","commonSituations":"Data-agent service down or returning 5xx with empty body; dataAgentConfig.getAgentUrl() misconfigured or pointing to a wrong port; proxy/gateway intercepting the request and returning an error page; serialization/deserialization mismatch after TableRagResult model changes.","solutions":["Verify dataAgentConfig.getAgentUrl() + TABLE_RAG_URL is reachable (curl the endpoint with an equivalent payload).","Log the raw response string res before parsing to see what the remote service actually returned.","Check data-agent service health/logs for the corresponding traceId/requestId.","Wrap the POST with retry/timeout handling so transient network failures surface as a clear upstream error instead of a null parse."],"exampleFix":"// before\nTableRagResult tableRagResult = JSONObject.parseObject(res, TableRagResult.class);\nif (tableRagResult == null || tableRagResult.getCode() == null) {\n    throw new RuntimeException(\"tableRag result is null\");\n}\n// after\nif (StringUtils.isBlank(res)) {\n    throw new RuntimeException(\"tableRag returned empty body, url=\" + dataAgentConfig.getAgentUrl() + TABLE_RAG_URL);\n}\nTableRagResult tableRagResult = JSONObject.parseObject(res, TableRagResult.class);\nif (tableRagResult == null || tableRagResult.getCode() == null) {\n    throw new RuntimeException(\"tableRag result unparseable, body=\" + res);\n}","handlingStrategy":"validation","validationCode":"// java\nif (StringUtils.isBlank(res)) {\n    throw new IllegalStateException(\"tableRag upstream returned empty body\");\n}","typeGuard":"TableRagResult safeParse(String res) {\n    if (StringUtils.isBlank(res)) return null;\n    try {\n        return JSONObject.parseObject(res, TableRagResult.class);\n    } catch (Exception e) {\n        return null;\n    }\n}","tryCatchPattern":"try {\n    TableRagResult r = tableRagService.tableRag(req);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"tableRag result is null\")) {\n        log.error(\"tableRag upstream unavailable, check dataAgent url/health\");\n    }\n    throw e;\n}","preventionTips":["Log the raw upstream response before parsing so bad bodies are visible.","Monitor data-agent endpoint health and configure timeouts on the HTTP client.","Pin/verify TableRagResult fields against the data-agent's actual response contract."],"tags":["upstream-service","null-response","http","java"],"backgroundTag":"empty-response-body","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"}