{"record":{"id":"e6203e2c973db86d","repo":"quickwit-oss/tantivy","slug":"storeplugin-is-a-built-in-use-storepluginwriter","errorCode":null,"errorMessage":"StorePlugin is a built-in; use StorePluginWriter::new","messagePattern":"StorePlugin is a built-in; use StorePluginWriter::new","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/store/plugin.rs","lineNumber":30,"sourceCode":"use crate::index::{SegmentComponent, SegmentReader};\nuse crate::indexer::doc_id_mapping::DocIdMapping;\nuse crate::plugin::{PluginMergeContext, PluginWriter, PluginWriterContext, SegmentPlugin};\nuse crate::schema::document::Document;\nuse crate::schema::Schema;\nuse crate::space_usage::{ComponentSpaceUsage, STORE};\nuse crate::store::{StoreReader, StoreWriter};\nuse crate::Segment;\n\n/// Built-in segment plugin that stores and merges stored documents.\npub struct StorePlugin;\n\nimpl SegmentPlugin for StorePlugin {\n    fn extensions(&self) -> &[&str] {\n        &[\"store\"]\n    }\n\n    fn create_writer(&self, _ctx: &PluginWriterContext) -> crate::Result<Box<dyn PluginWriter>> {\n        unimplemented!(\"StorePlugin is a built-in; use StorePluginWriter::new\")\n    }\n\n    fn merge(&self, ctx: PluginMergeContext) -> crate::Result<()> {\n        debug_time!(\"write-storable-fields\");\n        debug!(\"write-storable-fields\");\n\n        let path = ctx.target_segment.relative_path(SegmentComponent::Store);\n        let store_write = ctx.target_segment.index().directory().open_write(&path)?;\n        let settings = ctx.settings;\n        let mut store_writer = StoreWriter::new(\n            store_write,\n            settings.docstore_compression,\n            settings.docstore_blocksize,\n            settings.docstore_compress_dedicated_thread,\n        )?;\n\n        if !ctx.doc_id_mapping.is_trivial() {\n            debug!(\"non-trivial-doc-id-mapping\");","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/src/store/plugin.rs#L12-L48","documentation":"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.","triggerScenarios":"Invoking create_writer on StorePlugin (extensions: [\"store\"]) directly or via generic plugin enumeration when opening segment writers.","commonSituations":"Custom segment writer code iterating all registered plugins including built-ins; wrong plugin factory wiring that treats StorePlugin as a user plugin.","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."],"exampleFix":"// before\nlet writer = store_plugin.create_writer(&ctx)?; // unimplemented!\n// after\nlet writer = StorePluginWriter::new(ctx);","handlingStrategy":"type-guard","validationCode":"fn can_create_writer(plugin: &dyn SegmentPlugin) -> bool {\n    plugin.type_id() != std::any::TypeId::of::<StorePlugin>()\n}","typeGuard":"fn is_builtin_store(plugin: &dyn SegmentPlugin) -> bool {\n    plugin.type_id() == std::any::TypeId::of::<StorePlugin>()\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["unimplemented","plugin","store","built-in"],"backgroundTag":"built-in-plugin-misuse","analyzedSha":"b5d8deb80c26924e6b007a5b1a7630f35ca64de4","analyzedAt":"2026-09-05T13:20:51.521Z","contentChangedAt":"2026-09-05T13:20:51.521Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}