influxdata/influxdb · critical
schema contains repeated column name
Error message
schema contains repeated column name
What it means
In MutableBatch::try_into_arrow's conversion loop, the first occurrence of a field name consumes its column via std::mem::take (leaving None); a second schema field with the same name then finds None and panics with 'schema contains repeated column name'. Arrow schemas permit duplicate field names, so a projection or schema listing the same column twice triggers this.
Source
Thrown at core/mutable_batch/src/lib.rs:133
let Self {
column_names,
columns,
row_count: _,
} = self;
// Convert to Vec<Option<_>> to remove each Column avoid copying the
// underlying data
let mut columns = columns.into_iter().map(Some).collect::<Vec<_>>();
let arrays: Result<Vec<_>, Error> = schema
.iter()
.map(|(_, field)| {
let column_index = column_names
.get(field.name())
.expect("schema contains non-existent or column");
std::mem::take(&mut columns[*column_index])
.expect("schema contains repeated column name")
.try_into_arrow()
.context(ColumnSnafu {
column: field.name(),
})
})
.collect();
RecordBatch::try_new(schema.into(), arrays?).context(ArrowSnafu {})
}
/// Returns an iterator over the columns in this batch in no particular order
pub fn columns(&self) -> impl ExactSizeIterator<Item = (usize, &String, &Column)> + '_ {
self.column_names
.iter()
.map(move |(name, idx)| (*idx, name, &self.columns[*idx]))
}
/// Yield an iterator of column `(name, type)` tuples for all columns inView on GitHub (pinned to d28e26e048)
Solutions
- Deduplicate projection names before calling try_into_arrow (e.g. collect into a BTreeSet/IndexSet)
- Fix the schema construction that produced duplicate field names
- Assert uniqueness up front: assert_eq!(names.len(), dedup(names).len()) in tests around projection-building code
Example fix
// before let cols = ["time", "cpu", "cpu"]; // duplicate let rb = batch.try_into_arrow(Projection::Some(&cols))?; // after let cols: Vec<_> = cols.into_iter().collect::<std::collections::BTreeSet<_>>().into_iter().collect(); let rb = batch.try_into_arrow(Projection::Some(&cols))?;
Defensive patterns
Strategy: validation
Validate before calling
// dedupe projection names before use
let deduped: Vec<&str> = {
let seen: std::collections::BTreeSet<&str> = projection.iter().copied().collect();
seen.into_iter().collect()
};
assert_eq!(deduped.len(), projection.len(), "duplicate column names in projection");
Prevention
- Dedupe column lists at construction time (BTreeSet/IndexSet)
- Review wildcard-plus-explicit-column query building for accidental duplicates
- Unit-test projection builders with overlapping inputs
When it happens
Trigger: Passing Projection::Some with the same column name repeated; a schema built by concatenating two table schemas that both contain an identically named column; de-duplication lost during a merge.
Common situations: Programmatic projection construction from multiple sources without dedupe; wildcard 'SELECT *' plus explicit column names producing a duplicated list; schema merge during table evolution.
Related errors
- schema contains non-existent or column
- cannot fit duration into u64
- metric should be in progress
- no metric in progress
- can only accept once
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/46870be31159233e.
Report an issue: GitHub.