quickwit-oss/tantivy · error
StorePlugin is a built-in; use StorePluginWriter::new
Error message
StorePlugin is a built-in; use StorePluginWriter::new
What it means
StorePlugin::create_writer is deliberately unimplemented because stored-field writing is built into tantivy's segment writer; the store plugin only exposes merge. Users must create a StorePluginWriter directly with StorePluginWriter::new. Reaching this panic means the built-in plugin was dispatched through the generic plugin writer creation path.
Source
Thrown at src/store/plugin.rs:30
use crate::index::{SegmentComponent, SegmentReader};
use crate::indexer::doc_id_mapping::DocIdMapping;
use crate::plugin::{PluginMergeContext, PluginWriter, PluginWriterContext, SegmentPlugin};
use crate::schema::document::Document;
use crate::schema::Schema;
use crate::space_usage::{ComponentSpaceUsage, STORE};
use crate::store::{StoreReader, StoreWriter};
use crate::Segment;
/// Built-in segment plugin that stores and merges stored documents.
pub struct StorePlugin;
impl SegmentPlugin for StorePlugin {
fn extensions(&self) -> &[&str] {
&["store"]
}
fn create_writer(&self, _ctx: &PluginWriterContext) -> crate::Result<Box<dyn PluginWriter>> {
unimplemented!("StorePlugin is a built-in; use StorePluginWriter::new")
}
fn merge(&self, ctx: PluginMergeContext) -> crate::Result<()> {
debug_time!("write-storable-fields");
debug!("write-storable-fields");
let path = ctx.target_segment.relative_path(SegmentComponent::Store);
let store_write = ctx.target_segment.index().directory().open_write(&path)?;
let settings = ctx.settings;
let mut store_writer = StoreWriter::new(
store_write,
settings.docstore_compression,
settings.docstore_blocksize,
settings.docstore_compress_dedicated_thread,
)?;
if !ctx.doc_id_mapping.is_trivial() {
debug!("non-trivial-doc-id-mapping");View on GitHub (pinned to b5d8deb80c)
Solutions
- Create the writer via StorePluginWriter::new(...) instead of the trait method.
- Skip built-in plugins in generic create_writer dispatch.
- Fix plugin registration so StorePlugin is not routed through the user-plugin path.
- Upgrade tantivy if triggered from maintained code paths.
Example fix
// before let writer = store_plugin.create_writer(&ctx)?; // unimplemented! // after let writer = StorePluginWriter::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::<StorePlugin>()
} Type guard
fn is_builtin_store(plugin: &dyn SegmentPlugin) -> bool {
plugin.type_id() == std::any::TypeId::of::<StorePlugin>()
} Prevention
- Exclude StorePlugin from generic create_writer loops.
- Use StorePluginWriter::new for stored-field writers.
- Keep built-in vs user plugin lists separate in registration code.
When it happens
Trigger: Invoking create_writer on StorePlugin (extensions: ["store"]) directly or via generic plugin enumeration when opening segment writers.
Common situations: Custom segment writer code iterating all registered plugins including built-ins; wrong plugin factory wiring that treats StorePlugin as a user plugin.
Related errors
- InvertedIndexPlugin is a built-in; use InvertedIndexPluginWr
- 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/e6203e2c973db86d.
Report an issue: GitHub.