jd-opensource/joyagent-jdgenie · error · RuntimeException

modelCode:

Error message

modelCode:

What it means

Nl2SqlService.queryData parses each generated NL2SQL SELECT statement to extract the FROM table (the model code) and looks it up in the model schema map built from schemaInfo. If the parsed table name has no matching ChatModelInfoDto, the service cannot resolve columns or the physical table, so it throws RuntimeException("modelCode:<code>不存在") meaning the model code does not exist.

Solutions

  1. Check the modelCode printed in the exception and verify it exists in the data-agent's model schema list (schemaInfo / ChatModelInfoDto)
  2. Regenerate the NL2SQL with a prompt that restricts tables to the registered model codes
  3. Fix or restore the model code in the data-agent configuration if it was renamed or deleted
  4. Check for case or whitespace mismatch between the SQL FROM table and the modelCode key

Example fix

// before
String modelCode = sqlModel.getFromTable().getTableName();
ChatModelInfoDto modelInfo = modelMap.get(modelCode);
// after
String modelCode = sqlModel.getFromTable().getTableName();
ChatModelInfoDto modelInfo = modelMap.getOrDefault(modelCode.toLowerCase(), modelMap.get(modelCode));
if (modelInfo == null) {
    throw new RuntimeException("modelCode:" + modelCode + "不存在");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!modelMap.containsKey(sqlModel.getFromTable().getTableName())) {
    throw new IllegalArgumentException("unknown modelCode: " + sqlModel.getFromTable().getTableName());
}

Try / catch

try {
    queryData(request);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("modelCode:")) {
        log.error("Unknown model in NL2SQL result: {}", e.getMessage());
        // regenerate NL2SQL or return a friendly error to the caller
    } else throw e;
}

Prevention

When it happens

Trigger: The NL2SQL generated by the LLM references a table/model code not present in the schema info returned for this data agent: the model was renamed or deleted, the SQL hallucinates a table name, or the parsed FROM table differs in case/alias from the registered modelCode.

Common situations: LLM hallucinating table names on ambiguous schemas; a model (collection) deleted or renamed in the data-agent config while the prompt context still mentions it; case-sensitive mismatch between the SQL table name and modelCode; stale NL2SQL results reused after schema changes.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

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

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

    public List<ChatQueryData> queryData(NL2SQLReq request, NL2SQLResult nl2SQLResult) throws Exception {
        List<NL2SQLResult.NL2SQLData> data = nl2SQLResult.getData();
        List<ChatQueryData> dataList = new ArrayList<>();
        List<ChatModelInfoDto> schemaInfo = request.getSchemaInfo();
        Map<String, ChatModelInfoDto> modelMap = schemaInfo.stream().collect(Collectors.toMap(ChatModelInfoDto::getModelCode, v -> v));
        for (NL2SQLResult.NL2SQLData nl2SQLData : data) {
            SqlModel sqlModel = SqlParserUtils.parseSelectSql(nl2SQLData.getNl2sql(), dataAgentConfig.getDbConfig().getType());
            String modelCode = sqlModel.getFromTable().getTableName();
            ChatModelInfoDto modelInfo = modelMap.get(modelCode);
            if (modelInfo == null) {
                throw new RuntimeException("modelCode:" + modelCode + "不存在");
            }
            Map<String, ChatSchemaDto> columnMap = modelInfo.getSchemaList().stream().collect(Collectors.toMap(ChatSchemaDto::getColumnId, t -> t));
            List<ChatQueryColumn> chatQueryColumns = parseColumns(sqlModel, columnMap);
            List<ChatQueryFilter> chatQueryFilters = parseFilters(sqlModel, columnMap);
            String tableName = getTableName(modelInfo);
            String realSql = nl2SQLData.getNl2sql();
            for (String key : modelMap.keySet()) {
                realSql = realSql.replaceAll(key + "|`" + key + "`", tableName);
            }
            log.info("{},{} 执行sql:{}", request.getTraceId(), request.getRequestId(), realSql);
            JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest();
            DbConfig dbConfig = dataAgentConfig.getDbConfig();
            jdbcQueryRequest.setJdbcConnectionConfig(JdbcUtils.parseJdbcConnectionConfig(dbConfig));
            jdbcQueryRequest.setSql(realSql);
            QueryResult queryResult = jdbcDataProvider.queryData(jdbcQueryRequest);
            log.info("{},{} 查询sql结果大小:{}", request.getTraceId(), request.getRequestId(), queryResult.getDataSize());
            ChatQueryData queryData = new ChatQueryData();
            queryData.setColumnList(chatQueryColumns);

View on GitHub (pinned to 2417e0b8b6)