{"record":{"id":"e53c17266ee7c4e4","repo":"risingwavelabs/risingwave","slug":"schema-length-mismatch-risingwave-is-and-iceb","errorCode":null,"errorMessage":"Schema length mismatch, risingwave is {}, and iceberg is {}","messagePattern":"Schema length mismatch, risingwave is (.+?), and iceberg is (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/create_table.rs","lineNumber":399,"sourceCode":"                .to_arrow_field(\"\", our_field_type)\n                .map_err(|e| anyhow!(e))?\n                .data_type()\n                .clone();\n            bail!(\n                \"field {}'s type is incompatible\\nRisingWave converted data type: {}\\niceberg's data type: {}\",\n                arrow_field.name(),\n                converted_arrow_data_type,\n                arrow_field.data_type()\n            );\n        }\n    }\n    Ok(true)\n}\n\n/// Try to match our schema with iceberg schema.\npub fn try_matches_arrow_schema(rw_schema: &Schema, arrow_schema: &ArrowSchema) -> Result<()> {\n    if rw_schema.fields.len() != arrow_schema.fields().len() {\n        bail!(\n            \"Schema length mismatch, risingwave is {}, and iceberg is {}\",\n            rw_schema.fields.len(),\n            arrow_schema.fields.len()\n        );\n    }\n\n    let mut schema_fields = HashMap::new();\n    rw_schema.fields.iter().for_each(|field| {\n        let res = schema_fields.insert(field.name.as_str(), &field.data_type);\n        // This assert is to make sure there is no duplicate field name in the schema.\n        assert!(res.is_none())\n    });\n\n    check_compatibility(schema_fields, &arrow_schema.fields)?;\n\n    // The sink writes columns to the Iceberg table by position, so the column order\n    // must match. The check above only validates the name set and types.\n    for (idx, (rw_field, arrow_field)) in rw_schema","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/create_table.rs#L381-L417","documentation":"`try_matches_arrow_schema` first checks that the RisingWave sink schema and the Iceberg table's arrow schema have the same number of fields, bailing with a length-mismatch message otherwise. The sink writes columns by position, so column counts must be equal.","triggerScenarios":"Called from `create_and_validate_table_impl` (and tests): sink schema has N columns while the resolved Iceberg table arrow schema has M != N columns.","commonSituations":"Sink created from a query that selects a subset of the Iceberg table's columns; Iceberg table evolved (columns added/dropped) after the sink was created; misconfigured `create_table_if_not_exists` producing a table with different column count.","solutions":["Adjust the sink query so it selects exactly the same number of columns as the Iceberg table.","If the Iceberg table changed, recreate the sink to match the new schema.","If RW created the table but counts still differ, check that no parallel schema evolution altered the table."],"exampleFix":"// before: table has 3 columns\nCREATE SINK s AS SELECT a, b FROM t;\n// after\nCREATE SINK s AS SELECT a, b, c FROM t;","handlingStrategy":"validation","validationCode":"// assert equal column counts before sink creation\nassert_eq!(rw_schema.fields.len(), arrow_schema.fields().len(),\n    \"sink/table column count mismatch\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["SELECT exactly the table's columns — no subsets, no extras.","Re-create the sink when the Iceberg table evolves.","Diff the sink query's projection against the table DDL before deploying."],"tags":["iceberg","schema","column-count","compatibility"],"backgroundTag":"shape-mismatch","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}