zed-industries/zed · error

asset cache entries are keyed by their asset type

Error message

asset cache entries are keyed by their asset type

What it means

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.

Source

Thrown at crates/gpui/src/app.rs:2714

    /// Starts loading an uncached asset and returns its result once available.
    ///
    /// Pending loads and completed results are cached until [`Self::remove_asset`].
    /// This method does not subscribe a view to completion notifications.
    pub fn fetch_asset<A: Asset>(&mut self, source: &A::Source) -> Option<A::Output> {
        self.asset_entry::<A>(source).get()
    }

    pub(crate) fn asset_entry<A: Asset>(&mut self, source: &A::Source) -> &CachedLoad<A::Output> {
        let asset_id = (TypeId::of::<A>(), hash(source));
        if !self.loading_assets.contains_key(&asset_id) {
            let future = A::load(source.clone(), self);
            let entry = CachedLoad::new(future, self);
            self.loading_assets.insert(asset_id, Box::new(entry));
        }
        self.loading_assets
            .get(&asset_id)
            .and_then(|entry| entry.downcast_ref())
            .expect("asset cache entries are keyed by their asset type")
    }

    /// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
    /// for elements rendered within this window.
    #[track_caller]
    pub fn focus_handle(&self) -> FocusHandle {
        FocusHandle::new(&self.focus_handles)
    }

    /// Tell GPUI that an entity has changed and observers of it should be notified.
    pub fn notify(&mut self, entity_id: EntityId) {
        let window_invalidators = mem::take(
            self.window_invalidators_by_entity
                .entry(entity_id)
                .or_default(),
        );

        // `window_invalidators_by_entity` is monotonic, so an entry alone

View on GitHub (pinned to 9d272b0363)

Solutions

  1. Ensure the asset's Source type implements Hash and Eq consistently with its identity
  2. If two distinct sources collide, fix the Hash/Eq implementation of the source rather than the cache
  3. Use remove_asset to clear stale entries for a type when cached results must be invalidated
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/gpui/src/app.rs:2714 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-09-12). Data as JSON: /api/errors/5652ed8bd99eba96. Report an issue: GitHub.