apache/dolphinscheduler · error · UnsupportedOperationException

Invalid compatible mode: " + compatibleMode

Error message

Invalid compatible mode: " + compatibleMode

What it means

The mode-aware getValidationQuery(compatibleMode) recognizes only 'mysql' and 'oracle' (case-insensitive); any other/blank value falls through to an UnsupportedOperationException with the offending mode. It means the OceanBase datasource's compatibleMode parameter holds an unrecognized value.

Solutions

  1. Set compatibleMode to exactly 'mysql' or 'oracle' (case-insensitive, surrounding spaces tolerated) in the OceanBase datasource params
  2. Check for null/empty mode in the datasource creation request or saved config
  3. If a new mode is needed, extend the switch in OceanBaseDataSourceProcessor.getValidationQuery

Example fix

// before
{"type":"OCEANBASE","compatibleMode":"ob"}          // invalid
// after
{"type":"OCEANBASE","compatibleMode":"mysql"}
Defensive patterns

Strategy: validation

Validate before calling

String m = obParam.getCompatibleMode();
if (m == null || !(m.trim().equalsIgnoreCase("mysql") || m.trim().equalsIgnoreCase("oracle"))) {
  throw new IllegalArgumentException("compatibleMode must be 'mysql' or 'oracle', got: " + m);
}

Type guard

boolean isKnownMode(String m) {
  return m != null && ("mysql".equalsIgnoreCase(m.trim()) || "oracle".equalsIgnoreCase(m.trim()));
}

Try / catch

try {
  vq = processor.getValidationQuery(mode);
} catch (UnsupportedOperationException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Invalid compatible mode")) {
    vq = processor.getValidationQuery("mysql"); // safe default for OceanBase MySQL-mode tenants
  } else throw e;
}

Prevention

When it happens

Trigger: createConnectionParams -> getValidationQuery(compatibleMode) when compatibleMode is null, empty, misspelled (e.g. 'MySQL ', 'mariadb', 'ob'), or not one of mysql/oracle.

Common situations: Typo in compatibleMode config; leaving the mode unset in an automated datasource-creation request; tooling writing 'oracleMode'/'mysqlMode' instead of 'oracle'/'mysql'.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/2a248b2df4a5154e. Report an issue: GitHub.

Appendix: source

Thrown at dolphinscheduler-datasource-plugin/dolphinscheduler-datasource-oceanbase/src/main/java/org/apache/dolphinscheduler/plugin/datasource/oceanbase/param/OceanBaseDataSourceProcessor.java:125

    public String getDatasourceDriver() {
        return DataSourceConstants.COM_OCEANBASE_JDBC_DRIVER;
    }

    @Override
    public String getValidationQuery() {
        throw new UnsupportedOperationException("Can't get validation query without compatible mode");
    }

    public String getValidationQuery(String compatibleMode) {
        if (compatibleMode != null) {
            switch (compatibleMode.trim().toLowerCase()) {
                case "mysql":
                    return DataSourceConstants.MYSQL_VALIDATION_QUERY;
                case "oracle":
                    return DataSourceConstants.ORACLE_VALIDATION_QUERY;
            }
        }
        throw new UnsupportedOperationException("Invalid compatible mode: " + compatibleMode);

    }

    @Override
    public String getJdbcUrl(ConnectionParam connectionParam) {
        OceanBaseConnectionParam obConnectionParam = (OceanBaseConnectionParam) connectionParam;
        String jdbcUrl = obConnectionParam.getJdbcUrl();
        if (MapUtils.isNotEmpty(obConnectionParam.getOther())) {
            return String.format("%s?%s&%s", jdbcUrl, transformOther(obConnectionParam.getOther()), APPEND_PARAMS);
        }
        return String.format("%s?%s", jdbcUrl, APPEND_PARAMS);
    }

    private String transformOther(Map<String, String> paramMap) {
        if (MapUtils.isEmpty(paramMap)) {
            return null;
        }
        Map<String, String> otherMap = new HashMap<>();

View on GitHub (pinned to 02eac45a1b)