risingwavelabs/risingwave · error
version field not set
Error message
version field not set
What it means
`ColumnCatalog::version()` returned `None` when `new_alter` builds the new `ColIdGenerator`, i.e. the original table's column catalog has no schema version (next_column_id / version_id) recorded. The generator needs the persisted version to compute the next column id and bumped version id, so a missing version is treated as a fatal invariant breach (expect/panic).
Source
Thrown at src/frontend/src/handler/create_table/col_id_gen.rs:133
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 {
existing,
next_column_id: version.next_column_id,
version_id: version.version_id + 1,
}
}
/// Creates a new [`ColumnIdGenerator`] for a new table.
pub fn new_initial() -> Self {
Self {
existing: Existing::new(),
next_column_id: ColumnId::first_user_column(),
version_id: INITIAL_TABLE_VERSION_ID,
}
}
/// Generate [`ColumnId`]s for the given column and its nested fields (if any) recursively.View on GitHub (pinned to 6469eb736d)
Solutions
- Recreate the table so its catalog is rebuilt with a proper version field, then re-apply the ALTER.
- Backfill/migrate the persisted column catalog to include the version field.
- If this is a test fixture, construct the catalog via the normal create path so `version` is populated.
Example fix
// before: catalog built manually without version let catalog = ColumnCatalog::from(col_descs); // after: ensure version is set let catalog = ColumnCatalog::from(col_descs).with_version(SchemaVersion::new(1));
Defensive patterns
Strategy: type-guard
Validate before calling
if original.version().is_none() {
return Err("table catalog has no schema version; recreate the table".into());
} Type guard
fn has_version(c: &ColumnCatalog) -> bool { c.version().is_some() } Prevention
- Create tables only through supported SQL paths that set the version field
- Migrate legacy tables after upgrading before issuing ALTERs
- In tests, build catalogs via the standard constructors
When it happens
Trigger: ALTER TABLE on a table whose `ColumnCatalog` was constructed without a `version` field — e.g. a table created by legacy code paths or CDC/ingest paths that never set the version, then altered.
Common situations: Upgrading an old deployment whose tables were created before schema versioning was introduced, or hand-crafted test catalogs omitting `version`.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- duplicate path: {:?}
- 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/62114159d37d8830.
Report an issue: GitHub.