risingwavelabs/risingwave · error
duplicate path: {:?}
Error message
duplicate path: {:?} What it means
Panic inside `Existing::try_insert` during column-id collection: the same fully-qualified column path (e.g. a nested struct field path) was encountered twice while gathering the columns of the table being altered. `Existing` is a map from column path to (column_id, data_type), and a duplicate path means the original schema contains two columns resolving to the identical nested path, which is an invariant violation.
Source
Thrown at src/frontend/src/handler/create_table/col_id_gen.rs:117
handle(existing, path, ColumnId::placeholder(), list.elem().clone());
});
}
DataType::Map(map) => {
// There's no id for the key/value as map's own structure won't change.
with_segment!(Segment::MapKey, {
handle(existing, path, ColumnId::placeholder(), map.key().clone());
});
with_segment!(Segment::MapValue, {
handle(existing, path, ColumnId::placeholder(), map.value().clone());
});
}
data_types::simple!() => {}
}
existing
.try_insert(path.clone(), (id, data_type))
.unwrap_or_else(|_| panic!("duplicate path: {:?}", path));
}
let mut existing = Existing::new();
// Collect all existing fields into `existing`.
for col in original.columns() {
let mut path = vec![Segment::Field(col.name().to_owned())];
handle(
&mut existing,
&mut path,
col.column_id(),
col.data_type().clone(),
);
}
let version = original.version().expect("version field not set");
Self {View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect `SHOW CREATE TABLE` / the catalog for duplicate column or nested-field names and rename or drop one of them before altering.
- Recreate the table (create new, INSERT from old, swap names) if the catalog is already corrupted.
- If hit during development, add a uniqueness assertion when building the column list so the collision is caught at bind time instead of a panic.
Example fix
// before: ALTER TABLE t ADD COLUMN v struct<a int> while a path collision exists // after: drop the conflicting column first ALTER TABLE t DROP COLUMN v; ALTER TABLE t ADD COLUMN v struct<a int>;
Defensive patterns
Strategy: validation
Validate before calling
let mut seen = std::collections::HashSet::new();
for col in original.columns() {
// walk nested fields and collect paths; assert no duplicates before ALTER
if !seen.insert(col.name().to_string()) {
return Err(format!("duplicate column path: {}", col.name()));
}
} Prevention
- Ensure nested struct field names are unique within their level before altering
- Avoid concurrent ALTERs on the same table
- Rebuild catalogs through the normal create path rather than manual edits
When it happens
Trigger: Calling ALTER TABLE (via `new_alter` -> `handle`) on a table whose original columns produce two identical paths — e.g. a nested struct field path collides with another column path after case/normalization, or a corrupted catalog storing two fields at the same path.
Common situations: Altering a table whose schema was mutated by another concurrent ALTER, restoring a table from a catalog snapshot with duplicated nested fields, or bugs in schema evolution producing two struct fields with the same name at the same nesting level.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- version field not set
- column "{}" was persisted with legacy encoding thus cannot b
- column "{}" cannot be altered; only types containing struct
- incompatible data type change from {:?} to {:?} at path "{}"
- 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/daf98a8ee006cc93.
Report an issue: GitHub.