quickwit-oss/tantivy · error
InvertedIndexPlugin is a built-in; use InvertedIndexPluginWr
Error message
InvertedIndexPlugin is a built-in; use InvertedIndexPluginWriter::new
What it means
InvertedIndexPlugin's SegmentPlugin::create_writer is intentionally unimplemented because inverted index writing is built into tantivy's core segment writer. Users must construct an InvertedIndexPluginWriter via InvertedIndexPluginWriter::new instead of routing writes through the plugin trait. Hitting this means the generic plugin machinery incorrectly dispatched writer creation for the built-in plugin.
Source
Thrown at src/index/inverted_index_plugin.rs:69
// reallocation in the hashmap. Check if this affects performance.
.map(|power| 1 << power)
.take_while(|capacity| compute_table_memory_size(*capacity) < table_memory_upper_bound)
.last()
.ok_or_else(|| {
crate::TantivyError::InvalidArgument(format!(
"per thread memory budget (={per_thread_memory_budget}) is too small. Raise the \
memory budget or lower the number of threads."
))
})
}
impl SegmentPlugin for InvertedIndexPlugin {
fn extensions(&self) -> &[&str] {
&["fieldnorm", "term", "idx", "pos"]
}
fn create_writer(&self, _ctx: &PluginWriterContext) -> crate::Result<Box<dyn PluginWriter>> {
unimplemented!("InvertedIndexPlugin is a built-in; use InvertedIndexPluginWriter::new")
}
fn merge(&self, ctx: PluginMergeContext) -> crate::Result<()> {
// Field norms first: postings merge reads them back from the target segment.
merge_fieldnorms(&ctx)?;
debug_time!("write-postings");
debug!("write-postings");
let target_segment = ctx.target_segment;
let mut serializer = InvertedIndexSerializer::open(target_segment)?;
let fieldnorm_data = target_segment.open_read(SegmentComponent::FieldNorms)?;
let fieldnorm_readers = FieldNormReaders::open(fieldnorm_data)?;
write_postings_merge(
ctx.readers,
ctx.schema,
&mut serializer,
fieldnorm_readers,
ctx.doc_id_mapping,View on GitHub (pinned to b5d8deb80c)
Solutions
- Use InvertedIndexPluginWriter::new(...) to create the writer instead of the plugin trait method.
- Exclude InvertedIndexPlugin from any generic plugin create_writer dispatch loop.
- Register only non-built-in plugins in custom writer factories.
- Upgrade tantivy if this arises from core code paths.
Example fix
// before let writer = inverted_index_plugin.create_writer(&ctx)?; // unimplemented! // after let writer = InvertedIndexPluginWriter::new(ctx);
Defensive patterns
Strategy: type-guard
Validate before calling
fn can_create_writer(plugin: &dyn SegmentPlugin) -> bool {
plugin.type_id() != std::any::TypeId::of::<InvertedIndexPlugin>()
} Type guard
fn is_builtin_inverted_index(plugin: &dyn SegmentPlugin) -> bool {
plugin.type_id() == std::any::TypeId::of::<InvertedIndexPlugin>()
} Prevention
- Dispatch create_writer only to user-registered plugins; skip built-ins.
- Use InvertedIndexPluginWriter::new for inverted index writing.
- Centralize plugin factories so built-ins are never iterated generically.
When it happens
Trigger: Calling create_writer on an InvertedIndexPlugin instance, directly or via generic plugin-writer plumbing that resolves a plugin by its extensions ("fieldnorm", "term", "idx", "pos").
Common situations: Custom segment writer or tooling enumerating registered plugins and calling create_writer generically; incorrect plugin registration causing the built-in plugin to be treated as user-provided.
Related errors
- StorePlugin is a built-in; use StorePluginWriter::new
- Pre-tokenized string support in dynamic fields is not yet im
- Bytes support in dynamic fields is not yet implemented
- Facet support in dynamic fields is not yet implemented
- IP address support in dynamic fields is not yet implemented
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/d82887d27e422d43.
Report an issue: GitHub.