apache/seatunnel · error · IllegalArgumentException

RowType cannot be null

Error message

RowType cannot be null

What it means

DatabendUtil.convertToSeaTunnelRow also requires a non-null SeaTunnelRowType; a null rowType triggers IllegalArgumentException('RowType cannot be null'). The row type supplies the field names/arity used to size and populate the SeaTunnelRow, so conversion is impossible without it.

Source

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

        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;

                    if (value == null) {
                        log.info("Field {} ({}) [{}]: null", i, fieldName, fieldType.getSqlType());

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Initialize the SeaTunnelRowType from the catalog table schema before any row conversion occurs
  2. If the type is derived from config (e.g. schema option), verify that configuration produced a valid row type
  3. Guard the call: check rowType != null and fail fast with a clear message if the schema was never built

Example fix

// before
SeaTunnelRow row = DatabendUtil.convertToSeaTunnelRow(resultSet, rowType);
// after
Objects.requireNonNull(rowType, "rowType must be initialized from catalog schema before conversion");
SeaTunnelRow row = DatabendUtil.convertToSeaTunnelRow(resultSet, rowType);
Defensive patterns

Strategy: type-guard

Validate before calling

if (rowType == null) { throw new IllegalStateException("SeaTunnelRowType not initialized; ensure catalog schema was loaded"); }

Type guard

if (rowType == null || rowType.getFieldNames().length == 0) { return; }

Try / catch

try { row = DatabendUtil.convertToSeaTunnelRow(rs, rowType); } catch (IllegalArgumentException e) {
    if (e.getMessage().contains("RowType cannot be null")) { log.error("Schema/rowType was never initialized"); }
    throw e;
}

Prevention

When it happens

Trigger: Passing null as the SeaTunnelRowType argument - typically because the reader's catalog/type info was not initialized, getProducedType() returned null, or a variable holding the row type was never assigned before conversion.

Common situations: Custom readers built on the util before catalog initialization completed; config parsing that failed to derive the schema (e.g. missing schema option) silently yielding a null type; unit tests passing null.

Related errors


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