apache/seatunnel · error · org.apache.seatunnel.common.exception.SeaTunnelRuntimeException

COMMON-19

COMMON-19

Error message

'<identifier>' unsupported convert SeaTunnel data type '<dataType>' of '<field>' to connector data type.

What it means

This error is thrown by DuckDBTypeConverter.reconvert() when converting a SeaTunnel data type back to a DuckDB column type. The switch handles the supported DuckDB physical types (BOOLEAN, integer widths, float/double, DECIMAL, VARCHAR, DATE/TIME/TIMESTAMP variants, DUCKDB_BLOB for BYTES, etc.); any SeaTunnel type without a case reaches the default branch and CommonError.convertToConnectorTypeError is raised with the DUCKDB identifier, the SeaTunnel type's SQL type name, and the column name.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java:296

            case TIME:
                builder.columnType(DUCKDB_TIME);
                builder.dataType(DUCKDB_TIME);
                break;
            case TIMESTAMP:
                builder.columnType(DUCKDB_TIMESTAMP);
                builder.dataType(DUCKDB_TIMESTAMP);
                break;
            case TIMESTAMP_TZ:
                builder.columnType(DUCKDB_TIMESTAMP_WITH_TZ);
                builder.dataType(DUCKDB_TIMESTAMP_WITH_TZ);
                break;
            case BYTES:
                builder.columnType(DUCKDB_BLOB);
                builder.dataType(DUCKDB_BLOB);
                builder.length(column.getColumnLength());
                break;
            default:
                throw CommonError.convertToConnectorTypeError(
                        DatabaseIdentifier.DUCKDB,
                        column.getDataType().getSqlType().name(),
                        column.getName());
        }
        return builder.build();
    }

    private void reconvertDecimalType(
            Column column, BasicTypeDefine.BasicTypeDefineBuilder builder) {
        DecimalType decimalType = (DecimalType) column.getDataType();
        long precision =
                decimalType.getPrecision() > 0 ? decimalType.getPrecision() : DEFAULT_PRECISION;
        int scale = decimalType.getScale();
        if (precision > MAX_PRECISION) {
            log.warn(
                    "DECIMAL precision {} exceeds maximum {}, truncating to {}",
                    precision,
                    MAX_PRECISION,

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Convert complex fields to scalar types before the sink (e.g. serialize to STRING via a transform), so the DuckDB column type can be resolved.
  2. Pre-create the DuckDB table with explicit column types and disable auto creation (schema_save_mode = ERROR_WHEN_SCHEMA_NOT_EXIST).
  3. Filter out unsupported columns from the sink dataset.
  4. Upgrade SeaTunnel to a version with broader DuckDB type coverage.
  5. Extend DuckDBTypeConverter.reconvert() with a mapping for the missing SeaTunnel type if the data can be represented (e.g. MAP -> VARCHAR/JSON).

Example fix

// before: sink auto-creates table from schema containing ARRAY<INT>
sink {
  Jdbc {
    url = "jdbc:duckdb:/path/db.duckdb"
    schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
  }
}
// after: cast ARRAY to string upstream, or pre-create table
sink {
  Jdbc {
    url = "jdbc:duckdb:/path/db.duckdb"
    schema_save_mode = "ERROR_WHEN_SCHEMA_NOT_EXIST"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify the DuckDB sink schema only contains primitive types before writing
for (CatalogColumn col : catalogTable.getTableSchema().getColumns()) {
    if (!(col.getDataType() instanceof SeaTunnelPrimitiveType)) {
        throw new IllegalArgumentException(
            "Field " + col.getName() + " (" + col.getDataType().getSqlType()
            + ") has no DuckDB column mapping; flatten it or pre-create the table.");
    }
}

Type guard

static boolean isDuckDbWritable(SeaTunnelDataType<?> t) {
    return t instanceof SeaTunnelPrimitiveType; // composite types lack reconvert mappings
}

Try / catch

try {
    sinkWriter.write(...);
} catch (SeaTunnelRuntimeException e) {
    if (e.getMessage().contains("COMMON-19") && e.getMessage().contains("DUCKDB")) {
        throw new IllegalArgumentException("Flatten unsupported field or pre-create the DuckDB table", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Writing to DuckDB via the JDBC sink when DuckDB needs to derive the target column type (schema_save_mode creating the table, auto table creation, or schema evolution) and the SeaTunnel schema contains a type the converter cannot map — typically ARRAY, MAP, or ROW composite types, or time types without a matching DuckDB case.

Common situations: Piping data from a source that emits nested/complex types (JSON, Kafka formats, transforms producing MAP/ARRAY) into a DuckDB sink with automatic table creation enabled. Also occurs after upstream schema changes introduce a new field type.

Related errors


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