{"record":{"id":"b56fc461802e6215","repo":"OtterMind/Chat2DB","slug":"request-required","errorCode":"request.required","errorMessage":"request.required","messagePattern":"request\\.required","errorType":"validation","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDmlExecutionServiceImpl.java","lineNumber":112,"sourceCode":"    private List<ExecuteResponse> executeAndRecord(DbDmlExecutionRequest request,\n            ExecuteFunction executeFunction) {\n        boolean operationLogged = false;\n        DbDlExecuteRequest executeRequest = requireExecuteRequest(request);\n        try {\n            List<ExecuteResponse> results = executeFunction.execute(executeRequest);\n            sqlOperationLogRecorder.recordResultsAsync(results, request.getSource());\n            operationLogged = true;\n            attachLargeValueTokens(executeRequest, results);\n            return results;\n        } catch (RuntimeException e) {\n            recordFailureIfNeeded(executeRequest, request.getSource(), operationLogged, e);\n            throw e;\n        }\n    }\n\n    private DbDlExecuteRequest requireExecuteRequest(DbDmlExecutionRequest request) {\n        if (request == null || request.getExecuteRequest() == null) {\n            throw new BusinessException(\"request.required\");\n        }\n        return request.getExecuteRequest();\n    }\n\n    private void recordFailureIfNeeded(DbDlExecuteRequest executeRequest, String source, boolean operationLogged,\n            RuntimeException e) {\n        if (!operationLogged) {\n            sqlOperationLogRecorder.recordFailureAsync(executeRequest.getSql(), source, e.getMessage());\n        }\n    }\n\n    private void attachLargeValueTokens(DbDlExecuteRequest executeRequest, List<ExecuteResponse> results) {\n        if (CollectionUtils.isEmpty(results)) {\n            return;\n        }\n        for (ExecuteResponse executeResult : results) {\n            largeValueTokenService.attachTokens(largeValueTokensAttachRequest(executeRequest, executeResult));\n        }","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDmlExecutionServiceImpl.java#L94-L130","documentation":"Thrown by DbDmlExecutionServiceImpl.requireExecuteRequest when the inbound DbDmlExecutionRequest is null OR its nested getExecuteRequest() is null. It is a defensive guard that converts what would be an NPE into a BusinessException before the service touches result logging or SQL execution. Note the code 'request.required' is NOT defined in any messages_*.properties file, so the web convertor renders it as the raw string 'request.required : no message.' (I18nUtils falls back on NoSuchMessageException).","triggerScenarios":"Calling the DML execute API path with a null request body, or with a request whose executeRequest field was never populated (e.g. frontend built DbDmlExecutionRequest but omitted the DbDlExecuteRequest). Any caller that hits requireExecuteRequest(request) before constructing executeRequest triggers it.","commonSituations":"A client that skips the executeRequest field; a deserialization mismatch where the JSON shape changed (field renamed/removed); a programmatic test that passes a half-built request; integration after a DTO refactor where the nested object is now lazily set.","solutions":["Ensure the caller always populates request.getExecuteRequest() before calling execute(); validate the DTO contract on the controller/adapter layer.","If you are seeing this on a legit call, inspect the request JSON actually sent and confirm executeRequest serializes with the expected field name.","Add the missing i18n key 'request.required' to messages_en_US.properties (and other locales) so users see a real message instead of 'request.required : no message.'.","Return a 400-bound ParamBusinessException instead if this is purely a client-input problem."],"exampleFix":"// before\nDbDmlExecutionRequest req = new DbDmlExecutionRequest();\n// executeRequest never set\nservice.execute(req); // -> BusinessException(\"request.required\")\n\n// after\nDbDlExecuteRequest exec = DbDlExecuteRequest.builder().sql(sql).build();\nDbDmlExecutionRequest req = new DbDmlExecutionRequest();\nreq.setExecuteRequest(exec);\nservice.execute(req);","handlingStrategy":"validation","validationCode":"// Run before calling execute()\nif (request == null || request.getExecuteRequest() == null) {\n    throw new ParamBusinessException(\"executeRequest\");\n}\nservice.execute(request);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build the DTO fully on the adapter/client layer and assert executeRequest is non-null before submit.","Add a controller-layer @Valid / bean-validation constraint on the nested executeRequest field.","Add the i18n key 'request.required' so any leak shows a readable message."],"tags":["validation","request-validation","dml-execution","i18n-missing-key"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}