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
- Return `Vec::new()` when the active window is absent — an empty buffer list is the semantically correct answer here.
- In callers, skip LSP work when there is no active window (guard before calling buffers_for_language).
- Shut down or pause language servers during window/workspace teardown so quiescence events don't arrive windowless.
- 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
- Return empty collections for windowless states in query helpers.
- Pause LSP work when there is no active window.
- Shut down language servers before workspace teardown.
- Test LSP quiescence events arriving after the last window closes.
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
- active window present
- has_other_tab
- active window must have a populated split layout
- active window present
- active window present
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)