risingwavelabs/risingwave · error
incompatible data type change from {:?} to {:?} at path "{}"
Error message
incompatible data type change from {:?} to {:?} at path "{}" What it means
`ColIdGenerator::handle` detects an incompatible nested type change while reconciling original and new column trees: for paths where the type cannot be altered in place (non-compatible struct field changes, or differing `Vector` dimension/element types), it bails with both type names and the dotted path. This prevents silently producing a schema whose persisted rows cannot be decoded.
Source
Thrown at src/frontend/src/handler/create_table/col_id_gen.rs:206
path.push($segment);
let ret = $block;
path.pop();
ret
}};
}
let original_column_id = match this.existing.get(&*path) {
Some((original_column_id, original_data_type)) => {
// Only check the type name (discriminant) for compatibility check here.
// For nested fields, we will check them recursively later.
let incompatible = original_data_type.type_name() != data_type.type_name()
|| matches!(
(original_data_type, &data_type),
(DataType::Vector(old), DataType::Vector(new)) if old != new,
);
if incompatible {
let path = path.iter().join(".");
bail!(
"incompatible data type change from {:?} to {:?} at path \"{}\"",
original_data_type.type_name(),
data_type.type_name(),
path
);
}
Some(*original_column_id)
}
None => None,
};
// Only top-level column and struct fields need an ID.
let need_gen_id = matches!(path.last().unwrap(), Segment::Field(_));
let new_id = if need_gen_id {
if let Some(id) = original_column_id {
assert!(
id != ColumnId::placeholder(),View on GitHub (pinned to 6469eb736d)
Solutions
- Keep the inner type identical, or drop and re-add the column with the new nested type and backfill.
- For Vector columns, keep the dimension and element type unchanged; create a new column for a different dimension.
- Restructure the change as add-new-column + migrate + drop-old-column.
Example fix
-- before (incompatible at path 'a') ALTER TABLE t ALTER COLUMN s TYPE struct<a bigint>; -- after: add a new struct column instead ALTER TABLE t ADD COLUMN s2 struct<a bigint>; UPDATE t SET s2 = ROW(s.a::bigint); ALTER TABLE t DROP COLUMN s; ALTER TABLE t RENAME COLUMN s2 TO s;
Defensive patterns
Strategy: validation
Validate before calling
fn nested_types_compatible(orig: &DataType, new: &DataType) -> bool {
use DataType::*;
match (orig, new) {
(Struct(_), Struct(_)) => true,
(Vector(a), Vector(b)) => a == b,
(Struct(_), other) => other.contains_struct(),
_ => false,
}
} Prevention
- Keep inner struct field types stable when altering outer types
- Never change Vector dimension in place
- Prefer explicit new-column migration for nested type changes
When it happens
Trigger: ALTER TABLE changing a column type where at some nested path the original and new types differ incompatibly — e.g. `struct<a int>` to `struct<a bigint>` at path `a`, or `vector(3)` to `vector(4)`.
Common situations: Altering struct fields to widen/narrow inner types; changing vector index dimensionality for embedding columns.
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
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- column '{}' type mismatch: LanceDB type is {:?}, RisingWave
- duplicate path: {:?}
- version field not set
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9ef0fd49fa600c91.
Report an issue: GitHub.