{"record":{"id":"5652ed8bd99eba96","repo":"zed-industries/zed","slug":"asset-cache-entries-are-keyed-by-their-asset-type","errorCode":null,"errorMessage":"asset cache entries are keyed by their asset type","messagePattern":"asset cache entries are keyed by their asset type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gpui/src/app.rs","lineNumber":2714,"sourceCode":"    /// Starts loading an uncached asset and returns its result once available.\n    ///\n    /// Pending loads and completed results are cached until [`Self::remove_asset`].\n    /// This method does not subscribe a view to completion notifications.\n    pub fn fetch_asset<A: Asset>(&mut self, source: &A::Source) -> Option<A::Output> {\n        self.asset_entry::<A>(source).get()\n    }\n\n    pub(crate) fn asset_entry<A: Asset>(&mut self, source: &A::Source) -> &CachedLoad<A::Output> {\n        let asset_id = (TypeId::of::<A>(), hash(source));\n        if !self.loading_assets.contains_key(&asset_id) {\n            let future = A::load(source.clone(), self);\n            let entry = CachedLoad::new(future, self);\n            self.loading_assets.insert(asset_id, Box::new(entry));\n        }\n        self.loading_assets\n            .get(&asset_id)\n            .and_then(|entry| entry.downcast_ref())\n            .expect(\"asset cache entries are keyed by their asset type\")\n    }\n\n    /// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus\n    /// for elements rendered within this window.\n    #[track_caller]\n    pub fn focus_handle(&self) -> FocusHandle {\n        FocusHandle::new(&self.focus_handles)\n    }\n\n    /// Tell GPUI that an entity has changed and observers of it should be notified.\n    pub fn notify(&mut self, entity_id: EntityId) {\n        let window_invalidators = mem::take(\n            self.window_invalidators_by_entity\n                .entry(entity_id)\n                .or_default(),\n        );\n\n        // `window_invalidators_by_entity` is monotonic, so an entry alone","sourceCodeStart":2696,"sourceCodeEnd":2732,"githubUrl":"https://github.com/zed-industries/zed/blob/9d272b036335401f339d024ea94968fd51016c40/crates/gpui/src/app.rs#L2696-L2732","documentation":"In gpui's App::asset_entry (crates/gpui/src/app.rs:2714) asset cache entries are keyed by their asset type: the key is a tuple of TypeId::of::<A>() and a hash of the asset source. This means two different Asset types loading the same source do not collide, and the same type with different sources occupies separate slots. A key collision or miss indicates either two asset types hashing identically (practically impossible) or a source whose hash/equality does not reflect its identity, causing stale or duplicated loads.","triggerScenarios":"Thrown at crates/gpui/src/app.rs:2714 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the asset's Source type implements Hash and Eq consistently with its identity","If two distinct sources collide, fix the Hash/Eq implementation of the source rather than the cache","Use remove_asset to clear stale entries for a type when cached results must be invalidated"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"9d272b036335401f339d024ea94968fd51016c40","analyzedAt":"2026-09-12T19:35:53.743Z","contentChangedAt":"2026-09-12T19:35:53.743Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}