OtterMind/Chat2DB · error · BusinessException

request.required

request.required

Error message

request.required

What it means

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).

Source

Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDmlExecutionServiceImpl.java:112

    private List<ExecuteResponse> executeAndRecord(DbDmlExecutionRequest request,
            ExecuteFunction executeFunction) {
        boolean operationLogged = false;
        DbDlExecuteRequest executeRequest = requireExecuteRequest(request);
        try {
            List<ExecuteResponse> results = executeFunction.execute(executeRequest);
            sqlOperationLogRecorder.recordResultsAsync(results, request.getSource());
            operationLogged = true;
            attachLargeValueTokens(executeRequest, results);
            return results;
        } catch (RuntimeException e) {
            recordFailureIfNeeded(executeRequest, request.getSource(), operationLogged, e);
            throw e;
        }
    }

    private DbDlExecuteRequest requireExecuteRequest(DbDmlExecutionRequest request) {
        if (request == null || request.getExecuteRequest() == null) {
            throw new BusinessException("request.required");
        }
        return request.getExecuteRequest();
    }

    private void recordFailureIfNeeded(DbDlExecuteRequest executeRequest, String source, boolean operationLogged,
            RuntimeException e) {
        if (!operationLogged) {
            sqlOperationLogRecorder.recordFailureAsync(executeRequest.getSql(), source, e.getMessage());
        }
    }

    private void attachLargeValueTokens(DbDlExecuteRequest executeRequest, List<ExecuteResponse> results) {
        if (CollectionUtils.isEmpty(results)) {
            return;
        }
        for (ExecuteResponse executeResult : results) {
            largeValueTokenService.attachTokens(largeValueTokensAttachRequest(executeRequest, executeResult));
        }

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Ensure the caller always populates request.getExecuteRequest() before calling execute(); validate the DTO contract on the controller/adapter layer.
  2. If you are seeing this on a legit call, inspect the request JSON actually sent and confirm executeRequest serializes with the expected field name.
  3. 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.'.
  4. Return a 400-bound ParamBusinessException instead if this is purely a client-input problem.

Example fix

// before
DbDmlExecutionRequest req = new DbDmlExecutionRequest();
// executeRequest never set
service.execute(req); // -> BusinessException("request.required")

// after
DbDlExecuteRequest exec = DbDlExecuteRequest.builder().sql(sql).build();
DbDmlExecutionRequest req = new DbDmlExecutionRequest();
req.setExecuteRequest(exec);
service.execute(req);
Defensive patterns

Strategy: validation

Validate before calling

// Run before calling execute()
if (request == null || request.getExecuteRequest() == null) {
    throw new ParamBusinessException("executeRequest");
}
service.execute(request);

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/b56fc461802e6215. Report an issue: GitHub.