quickwit-oss/tantivy · error
Field already exists in schema {}
Error message
Field already exists in schema {} What it means
SchemaBuilder::add_field registers each field name uniquely in the schema's field map. Adding a field whose name already exists in the schema panics with 'Field already exists in schema <name>'. Field names are the primary lookup key, so duplicates are treated as a programming error rather than a recoverable error.
Source
Thrown at src/schema/schema.rs:221
pub fn add_custom_field<T: Into<String>>(
&mut self,
field_name: &str,
type_name: T,
params: serde_json::Value,
) -> Field {
let field_entry = FieldEntry::new_custom(
field_name.to_string(),
CustomOptions::new(type_name, params),
);
self.add_field(field_entry)
}
/// Adds a field entry to the schema in build.
pub fn add_field(&mut self, field_entry: FieldEntry) -> Field {
let field = Field::from_field_id(self.fields.len() as u32);
let field_name = field_entry.name().to_string();
if let Some(_previous_value) = self.fields_map.insert(field_name, field) {
panic!("Field already exists in schema {}", field_entry.name());
};
self.fields.push(field_entry);
field
}
/// Finalize the creation of a `Schema`
/// This will consume your `SchemaBuilder`
pub fn build(self) -> Schema {
Schema(Arc::new(InnerSchema {
fields: self.fields,
fields_map: self.fields_map,
}))
}
}
#[derive(Debug)]
struct InnerSchema {
fields: Vec<FieldEntry>,
fields_map: HashMap<String, Field>, // transientView on GitHub (pinned to b5d8deb80c)
Solutions
- De-duplicate field definitions before building: keep a HashSet of names and skip already-added ones.
- Check the builder's existing names first (e.g. via a helper on Schema/schema fields) before each add_*_field call.
- If merging schemas/configs, prefer explicit override semantics: replace the existing entry instead of adding a duplicate.
Example fix
// before
builder.add_u64_field("timestamp", Indexed);
builder.add_date_field("timestamp", Indexed); // panics
// after
let mut seen = HashSet::new();
if seen.insert("timestamp".to_string()) {
builder.add_date_field("timestamp", Indexed);
} Defensive patterns
Strategy: validation
Validate before calling
let mut names = HashSet::new();
if !names.insert(field_entry.name().to_string()) {
return Err(format!("duplicate field: {}", field_entry.name()));
}
builder.add_field(field_entry); Try / catch
// panic on duplicate name; guard before adding
assert!(!existing_names.contains(field_name), "duplicate schema field: {field_name}"); Prevention
- Track added field names in a HashSet while building schemas
- De-duplicate fields when merging config-driven field lists
- When loading saved schemas, don't re-add default fields on top
- Centralize schema construction in one function to avoid scattered adds
When it happens
Trigger: Calling SchemaBuilder::add_field (or any of add_u64_field/add_i64_field/add_f64_field/add_bool_field/add_date_field/add_ip_addr_field) with a field_entry whose name was already added to the builder in the current build.
Common situations: Programmatically building a schema from config where a field is listed twice (e.g. defaults plus user overrides both defining 'timestamp'); merging field lists from multiple sources; loops that re-add the same field name; loading a saved JSON schema and re-adding defaults on top.
Related errors
- support only up to u16::MAX field ids
- No multivalued index is allowed when stacking column index
- Internal Error: Called get_val of empty column.
- Corrupted data. Invalid VInt 32
- unsupported
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/0f007f78d1590a4e.
Report an issue: GitHub.