{"record":{"id":"a78d51d2765fb6e6","repo":"cocoindex-io/cocoindex","slug":"environment-provide-key-e","errorCode":null,"errorMessage":"Environment::provide_key({}): {e}","messagePattern":"Environment::provide_key\\((.+?)\\): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"rust/sdk/cocoindex/src/app.rs","lineNumber":173,"sourceCode":"                \"Environment::provide: type `{}` has already been provided\",\n                std::any::type_name::<T>()\n            );\n        }\n        self.state.insert(value);\n        self\n    }\n\n    /// Inject a shared resource by named [`ContextKey`].\n    ///\n    /// Named keys are useful when multiple resources share the same Rust type\n    /// and carry change-tracking.\n    ///\n    /// # Panics\n    /// Panics if a change-tracked key cannot fingerprint the provided value.\n    pub fn provide_key<T: Send + Sync + 'static>(mut self, key: &ContextKey<T>, value: T) -> Self {\n        self.context\n            .provide(key, value)\n            .unwrap_or_else(|e| panic!(\"Environment::provide_key({}): {e}\", key.name()));\n        self\n    }\n\n    /// Build the environment, opening (or creating) the LMDB database.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the LMDB database environment fails to initialize\n    /// (e.g., due to permissions, disk space, or a corrupted state directory).\n    pub async fn build(self) -> Result<Environment> {\n        // Register every `#[coco::function]`'s logic fingerprint into the engine's\n        // logic set, so memo entries that depend on them validate correctly\n        // (see `crate::logic`). Idempotent across builds.\n        crate::logic::register_all_fn_logic();\n\n        let db_path = self\n            .db_path\n            .unwrap_or_else(|| PathBuf::from(\"./coco_state\"));","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/rust/sdk/cocoindex/src/app.rs#L155-L191","documentation":"Environment::provide_key() stores a value under a named ContextKey; if the key is change-tracked, the provided value must be fingerprintable. When fingerprinting fails, the context provider returns an error and this method panics with the key name and reason. It indicates the value type cannot be hashed/fingerprinted for change detection.","triggerScenarios":"Calling builder.provide_key(&KEY, value) where KEY is a change-tracked ContextKey whose value type does not implement the fingerprinting trait, or whose fingerprint computation errors (e.g. contains an unfingerprintable nested type).","commonSituations":"Defining a custom ContextKey over a struct without implementing the required fingerprint trait; upgrading cocoindex and a previously fingerprintable type losing its impl; passing a closure or handle type that cannot be hashed.","solutions":["Implement the fingerprint trait for the value's type (or derive it if available).","Provide a fingerprintable projection instead (e.g. a connection-string String rather than the pool object).","Use plain provide() with a unique type if change tracking is not needed for this value.","Read the appended `{e}` message for the exact type that failed to fingerprint."],"exampleFix":"// before\nprovide_key(&APP_CFG_KEY, cfg) // cfg not fingerprintable\n\n// after\n#[derive(Fingerprint)]\nstruct AppConfig { dsn: String }\nprovide_key(&APP_CFG_KEY, AppConfig { dsn: cfg.dsn })","handlingStrategy":"validation","validationCode":"// ensure the value type implements the fingerprint trait before providing\nfn assert_fingerprintable<T: cocoindex::Fingerprint>(_v: &T) {}\nassert_fingerprintable(&value);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive/implement the fingerprint trait on every type stored under a change-tracked ContextKey.","Prefer fingerprintable projections (strings, ids) over opaque handles for keyed values.","Add a compile-time assertion test for fingerprint impls of config types."],"tags":["rust","panic","fingerprint","context"],"backgroundTag":"invalid-argument-value","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}