zed-industries/zed · error

Arena::end_scope called without a matching begin_scope

Error message

Arena::end_scope called without a matching begin_scope

What it means

Arena::end_scope decrements scope_depth and panics when it is already zero: end_scope was called without a matching begin_scope. An unbalanced end would let clear() free memory an enclosing scope still references, causing use-after-free, so the arena fails loudly instead.

Source

Thrown at crates/gpui/src/arena.rs:130

    /// Marks the start of a scope (e.g. a window draw) whose allocations must stay
    /// live until the scope ends, even if `clear` is called by a nested scope in
    /// the meantime.
    pub fn begin_scope(&mut self) {
        self.scope_depth += 1;
    }

    /// Ends the innermost scope started with `begin_scope`.
    ///
    /// Panics if no scope is active: an unbalanced `end_scope` would let `clear`
    /// run while an enclosing scope still references arena memory, which is
    /// exactly the use-after-free this bookkeeping exists to prevent, so failing
    /// loudly here is preferable.
    pub fn end_scope(&mut self) {
        self.scope_depth = self
            .scope_depth
            .checked_sub(1)
            .expect("Arena::end_scope called without a matching begin_scope");
    }

    /// Drops all allocations and resets the arena, unless a scope is still active.
    ///
    /// When a draw triggers a nested draw (e.g. re-entrant window procedure
    /// invocations on Windows, or opening a window from within a draw), the nested
    /// draw's clear must not free memory the outer draw still references, so it is
    /// deferred: the outer draw's own clear will drop both draws' allocations.
    pub fn clear(&mut self) {
        if self.scope_depth == 0 {
            self.force_clear();
        } else {
            log::debug!(
                "deferring arena clear; {} enclosing scope(s) still active",
                self.scope_depth
            );
        }
    }

View on GitHub (pinned to f4178619ac)

Solutions

  1. Ensure every end_scope is paired with exactly one begin_scope on the same code path
  2. Check early returns/panics between begin and end that skip the pairing
  3. Wrap scope usage in a guard type that ends the scope on drop
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/gpui/src/arena.rs:130 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/28cdd2d86a5b1b18. Report an issue: GitHub.