risingwavelabs/risingwave · error · anyhow::Error
field {}'s type is incompatible RisingWave converted data ty
Error message
field {}'s type is incompatible
RisingWave converted data type: {}
iceberg's data type: {} What it means
When a column exists in both schemas but its types are not compatible, `check_compatibility` bails with a detailed message listing the RisingWave-converted Arrow data type and the Iceberg table's Arrow data type. This is the sink refusing to write into a table whose column type cannot accept RisingWave's data.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:382
Ok(true)
}
(_, left, right) => Ok(left.equals_datatype(right)),
}
}
fn check_compatibility(
schema_fields: HashMap<&str, &risingwave_common::types::DataType>,
fields: &ArrowFields,
) -> anyhow::Result<bool> {
for arrow_field in fields {
let our_field_type = schema_fields
.get(arrow_field.name().as_str())
.ok_or_else(|| anyhow!("Field {} not found in our schema", arrow_field.name()))?;
if !field_is_compatible(our_field_type, arrow_field)? {
let converted_arrow_data_type = IcebergArrowConvert
.to_arrow_field("", our_field_type)
.map_err(|e| anyhow!(e))?
.data_type()
.clone();
bail!(
"field {}'s type is incompatible\nRisingWave converted data type: {}\niceberg's data type: {}",
arrow_field.name(),
converted_arrow_data_type,
arrow_field.data_type()
);
}
}
Ok(true)
}
/// Try to match our schema with iceberg schema.
pub fn try_matches_arrow_schema(rw_schema: &Schema, arrow_schema: &ArrowSchema) -> Result<()> {
if rw_schema.fields.len() != arrow_schema.fields().len() {
bail!(
"Schema length mismatch, risingwave is {}, and iceberg is {}",View on GitHub (pinned to 6469eb736d)
Solutions
- Compare the two printed data types in the message and CAST the sink column to match the Iceberg table type.
- If you own the table, recreate the Iceberg table with types derived from the RW schema (let RW create the table).
- For VARIANT columns, ensure both sides are VARIANT (plain structs won't be accepted).
- Ensure nested struct field names and order match exactly, since structs are compared positionally.
Example fix
// before: RW column is INTEGER, Iceberg table column is STRING CREATE SINK s AS SELECT id FROM t; // after CREATE SINK s AS SELECT id::VARCHAR AS id FROM t;
Defensive patterns
Strategy: validation
Validate before calling
// pre-validate each column type against the table before creating the sink
for (name, rw_t, arrow_f) in pairs {
if !field_is_compatible(rw_t, arrow_f)? {
eprintln!("column {name}: RW {:?} vs table {}", rw_t, arrow_f.data_type());
}
} Prevention
- CAST sink columns to the table's types in the SELECT list.
- Let RisingWave create the Iceberg table so types are derived from one schema.
- Watch the message's two printed types to pinpoint the mismatch quickly.
When it happens
Trigger: Called from `try_matches_arrow_schema`: `field_is_compatible` returns false for a column — e.g., RW INT vs Iceberg STRING, mismatched struct field names/order, mismatched list element types, VARIANT vs non-VARIANT.
Common situations: Creating a sink into a pre-existing Iceberg table with different column types; type changed in RisingWave after the Iceberg table was created; nested struct/list type drift; decimal precision differences are tolerated but other type differences are not.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Field {} not found in our schema
- Schema length mismatch, risingwave is {}, and iceberg is {}
- Column order mismatch at position {}: the sink has column `{
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/a1dab69759d77d1d.
Report an issue: GitHub.