apache/seatunnel · error · IllegalArgumentException

ResultSet cannot be null

Error message

ResultSet cannot be null

What it means

DatabendUtil.convertToSeaTunnelRow requires a non-null ResultSet; if a null is passed it throws IllegalArgumentException('ResultSet cannot be null'). This is a defensive API check because row conversion cannot proceed without an open result set to read fields from.

Source

Thrown at seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/util/DatabendUtil.java:125

        if (ssl != null) {
            properties.setProperty("ssl", ssl.toString());
        }

        try {
            return DriverManager.getConnection(url, properties);
        } catch (SQLException e) {
            throw new DatabendConnectorException(
                    DatabendConnectorErrorCode.CONNECT_FAILED,
                    "Failed to create connection to Databend: " + e.getMessage(),
                    e);
        }
    }

    /** Convert a ResultSet row to SeaTunnelRow */
    public static SeaTunnelRow convertToSeaTunnelRow(ResultSet resultSet, SeaTunnelRowType rowType)
            throws SQLException {
        if (resultSet == null) {
            throw new IllegalArgumentException("ResultSet cannot be null");
        }
        if (rowType == null) {
            throw new IllegalArgumentException("RowType cannot be null");
        }

        int arity = rowType.getFieldNames().length;
        Object[] fields = new Object[arity];
        log.info("Converting ResultSet to SeaTunnelRow with {} fields", arity);

        try {
            for (int i = 0; i < arity; i++) {
                int columnIndex = i + 1;
                String fieldName = rowType.getFieldName(i);
                SeaTunnelDataType<?> fieldType = rowType.getFieldType(i);

                try {
                    Object value = getFieldValue(resultSet, columnIndex, fieldType);
                    fields[i] = value;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure the ResultSet comes from a successfully executed statement.executeQuery(...) and is passed before closing
  2. Add a null check on the query result before invoking the converter and skip/error appropriately
  3. Check that executeQuery did not return null due to an earlier exception being swallowed upstream

Example fix

// before
SeaTunnelRow row = DatabendUtil.convertToSeaTunnelRow(resultSet, rowType);
// after
if (resultSet != null) {
    SeaTunnelRow row = DatabendUtil.convertToSeaTunnelRow(resultSet, rowType);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (resultSet == null) { throw new IllegalStateException("executeQuery returned no ResultSet; cannot convert rows"); }

Type guard

if (resultSet == null) { return; } // skip conversion when no result set

Try / catch

try { row = DatabendUtil.convertToSeaTunnelRow(rs, rowType); } catch (IllegalArgumentException e) {
    if (e.getMessage().contains("ResultSet cannot be null")) { log.error("Query produced no ResultSet"); }
    throw e;
}

Prevention

When it happens

Trigger: Calling convertToSeaTunnelRow(resultSet, rowType) with a null ResultSet - e.g. when a caller stored the result of a query that returned null, or passed an unset variable after a failed executeQuery path.

Common situations: Custom code (or a modified reader) invoking the util directly with the result of a statement that was never executed; test harnesses passing null; refactors where executeQuery's return value was lost before conversion.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/788a2c4010962318. Report an issue: GitHub.