Hmbown/CodeWhale · error
terminal clipboard writer stopped
Error message
terminal clipboard writer stopped
What it means
The terminal clipboard writer's background thread has exited, dropping its side of the std::sync::mpsc channel, so a new clipboard write request cannot be queued. enqueue() surfaces the Disconnected variant of try_send as this error to distinguish a dead writer from a merely busy one.
Solutions
- Recreate or reinitialize the terminal clipboard backend/writer thread before retrying the write
- Fall back to a direct clipboard write path (wlcopy / OSC52 handled elsewhere) instead of the terminal writer
- Discard the stale Clipboard handle and obtain a fresh one from the live terminal context
Example fix
// before
if let Err(err) = clipboard.write_text(text) {
eprintln!("copy failed: {err}");
}
// after
if let Err(err) = clipboard.write_text(text) {
if err.to_string().contains("writer stopped") {
clipboard = Clipboard::new(&terminal_context); // rebuild writer
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Best-effort liveness probe: a disconnected channel fails fast.
fn writer_alive(tx: &std::sync::mpsc::Sender<Request>) -> bool {
tx.send(Request::Ping).is_ok() // or check an AtomicBool liveness flag
} Type guard
fn is_disconnected(err: &anyhow::Error) -> bool {
err.to_string().contains("writer stopped")
} Try / catch
match clipboard.write_text(text) {
Ok(()) => {},
Err(e) if is_disconnected(&e) => rebuild_clipboard_writer_and_retry(),
Err(e) => log::warn!("clipboard unavailable: {e}"),
} Prevention
- Keep a liveness flag on the writer thread and check it before enqueueing
- Never attempt clipboard writes during/after terminal teardown
- Handle writer-thread panics so the channel stays usable or the handle is invalidated
When it happens
Trigger: Calling enqueue_terminal_write (via write_text with ClipboardWriteOrder::TerminalClientOnly) after the writer thread has terminated — typically because the worker saw a shutdown signal, panicked, or the TUI terminal context was torn down while a clipboard write was still attempted.
Common situations: Clipboard write racing app shutdown or terminal teardown; writer thread panic from an invalid escape-sequence target; a plugin or test harness keeping a stale Clipboard handle after the terminal backend was dropped.
Related errors
- another terminal clipboard write is still queued
- Clipboard unavailable
- OSC 52 clipboard fallback requires a terminal
- selection is too large for OSC 52 clipboard fallback
- background hook supervisor queue is full
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/a1f27a737d00c8d0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/clipboard.rs:291
})
.context("spawn terminal clipboard writer")?;
Ok(Self {
request_tx,
completion_rx,
})
}
fn enqueue(&self, text: &str, in_tmux: bool) -> Result<()> {
let request = TerminalClipboardWriteRequest {
text: text.to_string(),
in_tmux,
};
self.request_tx.try_send(request).map_err(|err| match err {
std::sync::mpsc::TrySendError::Full(_) => {
anyhow::anyhow!("another terminal clipboard write is still queued")
}
std::sync::mpsc::TrySendError::Disconnected(_) => {
anyhow::anyhow!("terminal clipboard writer stopped")
}
})
}
fn poll_completion(&self) -> Option<TerminalClipboardWriteCompletion> {
self.completion_rx.try_recv().ok()
}
}
/// Clipboard reader/writer helper.
pub struct ClipboardHandler {
terminal_context: TerminalClipboardContext,
terminal_writer: Option<TerminalClipboardWriter>,
#[cfg(all(target_os = "linux", not(target_env = "ohos"), not(test)))]
primary: Option<primary::PrimarySelection>,
#[cfg(test)]
primary_enabled: bool,
#[cfg(test)]View on GitHub (pinned to 73e0f67d83)