sinelaw/fresh · error

active window present

Error message

active window present

What it means

Panic from `Option::expect` in `App::buffers_for_language`, a read-only helper listing `(BufferId, LspUri)` pairs for buffers of a given language. It asserts the active window exists whenever LSP work (diagnostics pull, semantic tokens, folding, inlay hints) is requested. `windows.get(&self.active_window)` returning `None` panics instead of returning an empty list.

Solutions

  1. Return `Vec::new()` when the active window is absent — an empty buffer list is the semantically correct answer here.
  2. In callers, skip LSP work when there is no active window (guard before calling buffers_for_language).
  3. Shut down or pause language servers during window/workspace teardown so quiescence events don't arrive windowless.
  4. Keep `active_window` always pointing at a live window while LSP sessions are open.

Example fix

// before
self.windows
    .get(&self.active_window)
    .map(|w| &w.buffers)
    .expect("active window present")
    .iter()
    .filter_map(|(buffer_id, state)| { ... })
    .collect()
// after
self.windows
    .get(&self.active_window)
    .map(|w| &w.buffers)
    .map(|buffers| buffers.iter().filter_map(|(buffer_id, state)| { ... }).collect())
    .unwrap_or_default()
Defensive patterns

Strategy: validation

Validate before calling

if app.windows.get(&app.active_window).is_none() {
    return Vec::new(); // nothing to report for a nonexistent window
}

Type guard

fn active_buffers_ref(app: &App) -> Option<&BufferMap> {
    app.windows.get(&app.active_window).map(|w| &w.buffers)
}

Try / catch

// Default to empty instead of panicking:
app.windows.get(&app.active_window)
    .map(|w| &w.buffers)
    .map(|b| collect_language_buffers(b, language))
    .unwrap_or_default()

Prevention

When it happens

Trigger: Any of the callers (`handle_lsp_server_quiescent`, `pull_diagnostics_for_language`, `request_semantic_tokens_for_language`, `request_folding_ranges_for_language`, `request_inlay_hints_for_language`) running when the active window id is missing from `windows` — e.g. LSP quiescence event arriving after the last window closed.

Common situations: LSP server becomes ready right as the user closes the window/workspace; app teardown while LSP requests still fire; tests invoking LSP helpers with no window set up.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/30c603a7ff0b849f. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/app/async_messages.rs:74

    /// This is the single correct way to enumerate buffers for sending a
    /// per-URI LSP request (pull diagnostics, inlay hints, semantic tokens,
    /// folding ranges, …) to a language-scoped server. Without the language
    /// filter, a server configured only for e.g. "rust" ends up receiving
    /// requests for every open URI regardless of type, and a responsible
    /// server rejects unknown URIs with `file not found (code -32603)` —
    /// polluting logs and wasting a round-trip per unrelated buffer.
    ///
    /// Callers that need richer per-buffer info (line counts, content, file
    /// paths) can still iterate themselves, but should use the same
    /// `state.language == language` predicate this helper encodes.
    pub(crate) fn buffers_for_language(
        &self,
        language: &str,
    ) -> Vec<(BufferId, crate::app::types::LspUri)> {
        self.windows
            .get(&self.active_window)
            .map(|w| &w.buffers)
            .expect("active window present")
            .iter()
            .filter_map(|(buffer_id, state)| {
                if state.language != language {
                    return None;
                }
                self.active_window()
                    .buffer_metadata
                    .get(buffer_id)
                    .and_then(|m| m.file_uri().cloned())
                    .map(|uri| (*buffer_id, uri))
            })
            .collect()
    }

    /// Apply diagnostics to a buffer identified by URI.
    /// Returns `(buffer_id, actually_updated)` if buffer was found, None otherwise.
    /// `actually_updated` is false when the DIAG CACHE determined no overlay changes were needed.
    fn apply_diagnostics_to_buffer(

View on GitHub (pinned to 67894ca546)