risingwavelabs/risingwave · error
variant object cannot have duplicate field name `{field_name
Error message
variant object cannot have duplicate field name `{field_name}` What it means
Variant objects (like JSON objects) require unique field names, but RisingWave struct types may contain duplicate field names. reject_duplicate_field compares each field name against the previous one (fields are iterated in name order) and bails when a consecutive duplicate is found.
Source
Thrown at src/common/src/types/variant.rs:728
})
.sorted_by(|a, b| a.0.cmp(&b.0))
.collect_vec();
for (field, value) in entries {
let mut field_builder = ObjectFieldBuilder::new(field.as_str(), &mut object);
append_datum_value(value, map_type.value(), &mut field_builder)?;
}
object.finish();
}
(value, ty) => bail!("cannot convert {} as {ty} to variant", value.get_ident()),
}
Ok(())
}
/// Variant objects require unique field names, but RisingWave struct types allow duplicates.
/// Callers iterate fields in name order, so comparing against the previous name suffices.
fn reject_duplicate_field(previous: Option<&str>, field_name: &str) -> anyhow::Result<()> {
if previous == Some(field_name) {
bail!("variant object cannot have duplicate field name `{field_name}`");
}
Ok(())
}
fn append_struct(
value: super::StructRef<'_>,
struct_type: &StructType,
builder: &mut impl VariantBuilderExt,
) -> anyhow::Result<()> {
let mut object = builder
.try_new_object()
.context("failed to create variant struct object")?;
let fields = value
.iter_fields_ref()
.zip_eq_fast(struct_type.iter())
.sorted_by(|(_, (field_a, _)), (_, (field_b, _))| field_a.cmp(field_b));
let mut previous_field_name = None;
for (value, (field_name, field_type)) in fields {View on GitHub (pinned to 6469eb736d)
Solutions
- Rename one of the duplicate fields in the struct definition
- Deduplicate fields before conversion (drop or merge same-name fields)
- Change the struct definition so field names are unique
Example fix
// before struct<a int,a varchar> // duplicate 'a' // after struct<a int,a_str varchar>
Defensive patterns
Strategy: validation
Validate before calling
fn struct_fields_unique(ty: &StructType) -> bool {
let mut names: Vec<_> = ty.names().collect();
names.sort();
names.windows(2).all(|w| w[0] != w[1])
} Try / catch
if let Err(e) = append_struct(value, ty, &mut builder) {
if e.to_string().contains("duplicate field name") {
// rename fields or skip object export for this type
} else { return Err(e); }
} Prevention
- Enforce unique field names in struct definitions at schema creation time
- Rename duplicate columns before JSON/Variant export
- Add schema linting that rejects duplicate nested field names
When it happens
Trigger: Converting a RisingWave struct (or map) with duplicate field names to a Variant via append_struct / append_variant_value, e.g. `struct<a int,a varchar>`.
Common situations: Tables created with duplicate column names in nested structs (allowed in RW), then read/exported as JSON or Variant; JSON export jobs hitting this on legacy schemas.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- unsupported JSON number: {v}
- cannot convert {} as {ty} to variant
- invalid variant path `{original_path}`
- Invalid variant encoding
- Invalid struct encoding: {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/fbe29f63f26cee11.
Report an issue: GitHub.