{"record":{"id":"63dd366db69bb008","repo":"quickwit-oss/quickwit","slug":"metastore-factory-and-config-backends-do-not-match","errorCode":null,"errorMessage":"metastore factory and config backends do not match: {:?} vs. {:?}","messagePattern":"metastore factory and config backends do not match: (.+?) vs\\. (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-metastore/src/metastore_resolver.rs","lineNumber":183,"sourceCode":"    per_protocol_factories: HashMap<MetastoreBackend, (Box<dyn MetastoreFactory>, MetastoreConfig)>,\n}\n\nimpl MetastoreResolverBuilder {\n    pub fn register<S: MetastoreFactory>(\n        mut self,\n        metastore_factory: S,\n        metastore_config: MetastoreConfig,\n    ) -> Self {\n        self.per_protocol_factories.insert(\n            metastore_factory.backend(),\n            (Box::new(metastore_factory), metastore_config),\n        );\n        self\n    }\n\n    pub fn build(self) -> anyhow::Result<MetastoreResolver> {\n        for (metastore_factory, metastore_config) in self.per_protocol_factories.values() {\n            ensure!(\n                metastore_factory.backend() == metastore_config.backend(),\n                \"metastore factory and config backends do not match: {:?} vs. {:?}\",\n                metastore_factory.backend(),\n                metastore_config.backend(),\n            );\n        }\n        let metastore_resolver = MetastoreResolver {\n            per_backend_factories: Arc::new(self.per_protocol_factories),\n        };\n        Ok(metastore_resolver)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::str::FromStr;\n\n    use super::*;","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-metastore/src/metastore_resolver.rs#L165-L201","documentation":"MetastoreResolver::build validates its internal state: for every protocol it registers, the registered metastore factory's backend() must equal the backend declared for that protocol in the resolver's config map. A mismatch means the builder was given inconsistent registrations (e.g. a factory registered under a URI scheme whose config backend differs). This is an internal consistency check to catch builder misuse.","triggerScenarios":"Calling `MetastoreResolverBuilder::build()` after registering a metastore factory under a protocol whose configured backend does not match the factory's backend, typically via `register_factory`/config registration with mismatched schemes.","commonSituations":"Custom metastore extensions registering a factory under the wrong URI scheme; code wiring a postgres factory to the file protocol (or vice versa); refactoring backend enums so backend() changed while registration keys stayed stale.","solutions":["Check each `register_factory(protocol, ...)` call and ensure the factory's backend matches the backend configured for that protocol.","Update the protocol key so it matches the factory's backend (e.g. register a PostgreSQL factory under `postgres`).","If this appears without custom code, report it — it indicates an internal wiring bug in Quickwit."],"exampleFix":"// before\nresolver.register_factory(\"postgres\", FileMetastoreFactory::default());\n// after\nresolver.register_factory(\"postgres\", PostgresqlMetastoreFactory::default());","handlingStrategy":"validation","validationCode":"// assert before build()\nassert_eq!(factory.backend(), config_backend_for_protocol(protocol),\n    \"factory/config backend mismatch for protocol {protocol}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive the protocol key from the factory's backend() instead of hardcoding scheme strings.","Add a unit test that builds a resolver with every registered factory/config pair.","Keep factory registration and config parsing in one place to avoid drift."],"tags":["metastore","resolver","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}