zed-industries/zed · error

update_window returned Err without invoking the closure

Error message

update_window returned Err without invoking the closure

What it means

This expect fires in AsyncWindowContext::new when App::update_window fails (window no longer exists), so the fallback path calls app.new on the main App to build the entity anyway; it panics only if the same FnOnce closure was already consumed — a logic bug, not an expected failure.

Source

Thrown at crates/gpui/src/app/async_context.rs:393

impl AppContext for AsyncWindowContext {
    fn new<T>(&mut self, build_entity: impl FnOnce(&mut Context<T>) -> T) -> Entity<T>
    where
        T: 'static,
    {
        let mut build_entity = Some(build_entity);
        match self.app.update_window(self.window, |_, _, cx| {
            cx.new(
                build_entity
                    .take()
                    .expect("build_entity is taken exactly once"),
            )
        }) {
            Ok(entity) => entity,
            Err(_) => self.app.new(
                build_entity
                    .take()
                    .expect("update_window returned Err without invoking the closure"),
            ),
        }
    }

    fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> {
        self.app.reserve_entity()
    }

    fn insert_entity<T: 'static>(
        &mut self,
        reservation: Reservation<T>,
        build_entity: impl FnOnce(&mut Context<T>) -> T,
    ) -> Entity<T> {
        let mut args = Some((reservation, build_entity));
        match self.app.update_window(self.window, |_, _, cx| {
            let (reservation, build_entity) = args.take().expect("args are taken exactly once");
            cx.insert_entity(reservation, build_entity)
        }) {

View on GitHub (pinned to f4178619ac)

Solutions

  1. Verify update_window's Err is due to a closed window and that the closure was never invoked before taking build_entity
  2. Ensure the build_entity closure is only moved into one branch; take() must succeed exactly once
  3. If this fires, audit callers passing the same closure to both update_window and the fallback new()
Defensive patterns

Strategy: fallback

When it happens

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

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/20eb853d3e7dbe7d. Report an issue: GitHub.