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
- 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.
- Pre-create the DuckDB table with explicit column types and disable auto creation (schema_save_mode = ERROR_WHEN_SCHEMA_NOT_EXIST).
- Filter out unsupported columns from the sink dataset.
- Upgrade SeaTunnel to a version with broader DuckDB type coverage.
- 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
- Do not pipe JSON/Kafka nested fields straight into a DuckDB sink with auto table creation; convert MAP/ARRAY/ROW to STRING first.
- Pre-create DuckDB tables with explicit types and set schema_save_mode = ERROR_WHEN_SCHEMA_NOT_EXIST.
- Re-check the upstream schema whenever source tables change.
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.