zellij-org/zellij · warning · anyhow::Error
Could not find editor pane to replace
Error message
Could not find editor pane to replace
What it means
Logged (non_fatal) by Tab::replace_pane_with_editor_pane when the pane targeted by `pane_id_to_replace` exists neither in the floating pane set nor in the tiled pane set. The function looks the pane up in floating_panes.panes_contain / tiled_panes.replace_pane; both miss, so the editor pane cannot be swapped in and the request is dropped after logging.
Source
Thrown at zellij-server/src/tab/mod.rs:3172
None
};
match replaced_pane {
Some(replaced_pane) => {
resize_pty!(
replaced_pane,
self.os_api,
self.senders,
self.character_cell_size
)
.non_fatal();
self.track_stack_list_member_id_swap(
pane_id_to_replace,
PaneId::Terminal(pid),
);
self.insert_scrollback_editor_replaced_pane(replaced_pane, pid);
},
None => {
Err::<(), _>(anyhow!("Could not find editor pane to replace"))
.with_context(err_context)
.non_fatal();
},
}
},
PaneId::Plugin(_pid) => {
// TBD, currently unsupported
},
}
Ok(())
}
pub fn suppress_pane_and_replace_with_pid(
&mut self,
old_pane_id: PaneId,
new_pane_id: PaneId,
close_replaced_pane: bool,
run: Option<Run>,
completion_tx: Option<NotificationEnd>,View on GitHub (pinned to 98a0837077)
Solutions
- Confirm the target pane still exists before issuing the edit/replace request (check pane list via plugin API or tab bar)
- If this appears from a plugin, re-query focus/pane state instead of caching PaneId values across events
- For scrollback editing, edit a live pane's scrollback rather than one whose process has exited
- Treat as benign in logs unless editor panes visibly fail to open; then report the race upstream with a reproduction
Example fix
// before
let replaced_pane = if self.floating_panes.panes_contain(&pane_id_to_replace) { ... } else { self.tiled_panes.replace_pane(...) };
match replaced_pane {
None => Err(anyhow!("Could not find editor pane to replace")).with_context(err_context).non_fatal(),
...
}
// after: include the stale id in the log for diagnosis
None => Err(anyhow!("Could not find pane {pane_id_to_replace:?} to replace with editor pane"))
.with_context(err_context).non_fatal(), Defensive patterns
Strategy: validation
Validate before calling
// check the target pane still exists before requesting replacement
if tab.get_pane_with_id(pane_id_to_replace).is_none() {
log::debug!("pane {pane_id_to_replace:?} is gone; skipping editor replacement");
return Ok(());
} Type guard
fn pane_is_replacable(tab: &Tab, pane_id: PaneId) -> bool {
tab.get_pane_with_id(pane_id).is_some()
} Try / catch
// non_fatal path only logs; wrap callers that must not continue blindly:
if let Err(e) = tab.replace_pane_with_editor_pane(pid, pane_id_to_replace) {
log::debug!("editor replacement failed for {pane_id_to_replace:?}: {e:#}");
} Prevention
- Never cache PaneId values across async boundaries; re-resolve from live state at call time
- For scrollback edits, target panes whose process is still alive
- In plugins, re-query pane lists after pane-close events instead of reusing ids captured earlier
When it happens
Trigger: Requesting an editor-pane replacement for a specific pane id (scrollback edit / command pane targeting a pane id) after that pane has already been closed, exited, or moved to the suppressed set. The id is stale at the moment the replacement runs.
Common situations: Pane closes (process exit, Ctrl-d, close-pane key) racing an in-flight edit request; editing scrollback of a pane that exited while the edit action was queued; pane ids captured by a plugin or script and reused after the pane was gone; session resurrection replaying stale pane ids.
Related errors
- failed to find pane with id {pane_id:?}
- Could not find editor pane to replace - is no pane focused?
- Failed to find pane {pane_id:?}
- Failed to find pane {active_pane_id:?}
- failed to find active pane id for client {client_id}
AI-assisted analysis of zellij-org/zellij@98a0837077 (2026-08-16).
Data as JSON: /api/errors/01d87d374d7d16a7.
Report an issue: GitHub.