{"record":{"id":"1f88cd186e212b3d","repo":"quickwit-oss/tantivy","slug":"fastfieldsplugin-is-a-built-in-use-fastfieldsplug","errorCode":null,"errorMessage":"FastFieldsPlugin is a built-in; use FastFieldsPluginWriter::new","messagePattern":"FastFieldsPlugin is a built-in; use FastFieldsPluginWriter::new","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/fastfield/plugin.rs","lineNumber":34,"sourceCode":"use crate::fastfield::{FastFieldReaders, FastFieldsWriter};\nuse crate::index::{SegmentComponent, SegmentReader};\nuse crate::indexer::doc_id_mapping::{DocIdMapping, MappingType, SegmentDocIdMapping};\nuse crate::plugin::{PluginMergeContext, PluginWriter, PluginWriterContext, SegmentPlugin};\nuse crate::schema::document::Document;\nuse crate::schema::{value_type_to_column_type, Schema};\nuse crate::space_usage::{ComponentSpaceUsage, FAST_FIELDS};\nuse crate::Segment;\n\n/// Built-in segment plugin that stores and merges fast-field columns.\npub struct FastFieldsPlugin;\n\nimpl SegmentPlugin for FastFieldsPlugin {\n    fn extensions(&self) -> &[&str] {\n        &[\"fast\"]\n    }\n\n    fn create_writer(&self, _ctx: &PluginWriterContext) -> crate::Result<Box<dyn PluginWriter>> {\n        unimplemented!(\"FastFieldsPlugin is a built-in; use FastFieldsPluginWriter::new\")\n    }\n\n    fn merge(&self, ctx: PluginMergeContext) -> crate::Result<()> {\n        debug_time!(\"write-fast-fields\");\n        let path = ctx\n            .target_segment\n            .relative_path(SegmentComponent::FastFields);\n        let mut fast_field_wrt: WritePtr =\n            ctx.target_segment.index().directory().open_write(&path)?;\n\n        let required_columns = extract_fast_field_required_columns(ctx.schema);\n        let columnars: Vec<&ColumnarReader> = ctx\n            .readers\n            .iter()\n            .map(|reader| reader.fast_fields().columnar())\n            .collect();\n\n        // Clone the doc_id_mapping since convert_to_merge_order consumes it by value","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/src/fastfield/plugin.rs#L16-L52","documentation":"FastFieldsPlugin implements SegmentPlugin, but it is a built-in whose fast-field files are written by the segment writer itself. Its SegmentPlugin::create_writer deliberately panics with unimplemented!(); callers must construct FastFieldsPluginWriter directly instead of asking the plugin to create a writer.","triggerScenarios":"Calling FastFieldsPlugin.create_writer(ctx) — e.g. registering the plugin in a generic plugin pipeline that invokes create_writer for every plugin, or calling it manually.","commonSituations":"Misconfigured plugin registry treating the built-in plugin like an external one; custom segment-writer code iterating plugins and calling create_writer unconditionally.","solutions":["Use FastFieldsPluginWriter::new directly to create the fast-field writer","Exclude FastFieldsPlugin from generic create_writer dispatch; special-case it (fast fields are handled internally during segment writing)","Remove the plugin from any list of plugins expected to provide writers"],"exampleFix":"// before\nlet writer = fast_fields_plugin.create_writer(ctx)?;\n// after\nlet writer = FastFieldsPluginWriter::new(/* ... */);","handlingStrategy":"type-guard","validationCode":"// only call create_writer on non-builtin plugins\nif std::any::type_name::<P>() != \"tantivy::fastfield::plugin::FastFieldsPlugin\" {\n    let writer = plugin.create_writer(ctx)?;\n}","typeGuard":"fn builtin_fast_fields_plugin(p: &dyn SegmentPlugin) -> bool {\n    p.extensions() == &[\"fast\"] && std::any::type_name_of_val(p).contains(\"FastFieldsPlugin\")\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| plugin.create_writer(ctx)));\nmatch result {\n    Ok(w) => use_writer(w),\n    Err(_) => eprintln!(\"builtin plugin: use FastFieldsPluginWriter::new instead\"),\n}","preventionTips":["Never call create_writer on FastFieldsPlugin; construct FastFieldsPluginWriter::new","Special-case built-in plugins in generic plugin pipelines","Read SegmentPlugin docs to see which hooks are implemented per plugin","Keep built-ins out of user-registered plugin lists"],"tags":["rust","api-misuse","fast-fields","plugin","panic"],"backgroundTag":"api-misuse-internal-hook","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"}