{"record":{"id":"a012dc6ace00f478","repo":"jd-opensource/joyagent-jdgenie","slug":"modelcode","errorCode":null,"errorMessage":"modelCode:","messagePattern":"modelCode:","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"genie-backend/src/main/java/com/jd/genie/service/Nl2SqlService.java","lineNumber":134,"sourceCode":"            return modelInfo.getContent();\n        } else if (\"sql\".equalsIgnoreCase(modelInfo.getType())) {\n            return \"(\" + modelInfo.getContent() + \") t\";\n        } else {\n            throw new RuntimeException(\"不支持的模型类型\" + modelInfo.getType());\n        }\n    }\n\n    public List<ChatQueryData> queryData(NL2SQLReq request, NL2SQLResult nl2SQLResult) throws Exception {\n        List<NL2SQLResult.NL2SQLData> data = nl2SQLResult.getData();\n        List<ChatQueryData> dataList = new ArrayList<>();\n        List<ChatModelInfoDto> schemaInfo = request.getSchemaInfo();\n        Map<String, ChatModelInfoDto> modelMap = schemaInfo.stream().collect(Collectors.toMap(ChatModelInfoDto::getModelCode, v -> v));\n        for (NL2SQLResult.NL2SQLData nl2SQLData : data) {\n            SqlModel sqlModel = SqlParserUtils.parseSelectSql(nl2SQLData.getNl2sql(), dataAgentConfig.getDbConfig().getType());\n            String modelCode = sqlModel.getFromTable().getTableName();\n            ChatModelInfoDto modelInfo = modelMap.get(modelCode);\n            if (modelInfo == null) {\n                throw new RuntimeException(\"modelCode:\" + modelCode + \"不存在\");\n            }\n            Map<String, ChatSchemaDto> columnMap = modelInfo.getSchemaList().stream().collect(Collectors.toMap(ChatSchemaDto::getColumnId, t -> t));\n            List<ChatQueryColumn> chatQueryColumns = parseColumns(sqlModel, columnMap);\n            List<ChatQueryFilter> chatQueryFilters = parseFilters(sqlModel, columnMap);\n            String tableName = getTableName(modelInfo);\n            String realSql = nl2SQLData.getNl2sql();\n            for (String key : modelMap.keySet()) {\n                realSql = realSql.replaceAll(key + \"|`\" + key + \"`\", tableName);\n            }\n            log.info(\"{},{} 执行sql:{}\", request.getTraceId(), request.getRequestId(), realSql);\n            JdbcQueryRequest jdbcQueryRequest = new JdbcQueryRequest();\n            DbConfig dbConfig = dataAgentConfig.getDbConfig();\n            jdbcQueryRequest.setJdbcConnectionConfig(JdbcUtils.parseJdbcConnectionConfig(dbConfig));\n            jdbcQueryRequest.setSql(realSql);\n            QueryResult queryResult = jdbcDataProvider.queryData(jdbcQueryRequest);\n            log.info(\"{},{} 查询sql结果大小：{}\", request.getTraceId(), request.getRequestId(), queryResult.getDataSize());\n            ChatQueryData queryData = new ChatQueryData();\n            queryData.setColumnList(chatQueryColumns);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/jd-opensource/joyagent-jdgenie/blob/2417e0b8b636d941ad5fb14c59b20dddfef5375d/genie-backend/src/main/java/com/jd/genie/service/Nl2SqlService.java#L116-L152","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the modelCode printed in the exception and verify it exists in the data-agent's model schema list (schemaInfo / ChatModelInfoDto)","Regenerate the NL2SQL with a prompt that restricts tables to the registered model codes","Fix or restore the model code in the data-agent configuration if it was renamed or deleted","Check for case or whitespace mismatch between the SQL FROM table and the modelCode key"],"exampleFix":"// before\nString modelCode = sqlModel.getFromTable().getTableName();\nChatModelInfoDto modelInfo = modelMap.get(modelCode);\n// after\nString modelCode = sqlModel.getFromTable().getTableName();\nChatModelInfoDto modelInfo = modelMap.getOrDefault(modelCode.toLowerCase(), modelMap.get(modelCode));\nif (modelInfo == null) {\n    throw new RuntimeException(\"modelCode:\" + modelCode + \"不存在\");\n}","handlingStrategy":"validation","validationCode":"if (!modelMap.containsKey(sqlModel.getFromTable().getTableName())) {\n    throw new IllegalArgumentException(\"unknown modelCode: \" + sqlModel.getFromTable().getTableName());\n}","typeGuard":null,"tryCatchPattern":"try {\n    queryData(request);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"modelCode:\")) {\n        log.error(\"Unknown model in NL2SQL result: {}\", e.getMessage());\n        // regenerate NL2SQL or return a friendly error to the caller\n    } else throw e;\n}","preventionTips":["Always generate NL2SQL with the prompt restricted to registered model codes","Validate the FROM table against the model map before executing further parsing","Keep model codes normalized (consistent case) between schema registration and SQL generation"],"tags":["java","nl2sql","validation"],"backgroundTag":"entity-not-found","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"}