{"record":{"id":"baca2d9b39c33267","repo":"Hmbown/CodeWhale","slug":"failed-to-write-to-label-e","errorCode":null,"errorMessage":"Failed to write to {label}: {e}","messagePattern":"Failed to write to (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/clipboard.rs","lineNumber":541,"sourceCode":"\n#[cfg(all(any(target_os = \"macos\", target_os = \"windows\"), not(test)))]\nfn write_text_with_stdin_command(\n    program: &str,\n    args: &[&str],\n    text: &str,\n    label: &str,\n) -> Result<()> {\n    let mut child = Command::new(program)\n        .args(args)\n        .stdin(Stdio::piped())\n        .stdout(Stdio::null())\n        .stderr(Stdio::null())\n        .spawn()\n        .map_err(|e| anyhow::anyhow!(\"Failed to run {label}: {e}\"))?;\n    if let Some(mut stdin) = child.stdin.take() {\n        stdin\n            .write_all(text.as_bytes())\n            .map_err(|e| anyhow::anyhow!(\"Failed to write to {label}: {e}\"))?;\n    }\n    let _ = std::thread::Builder::new()\n        .name(\"clipboard-wait\".to_string())\n        .spawn(move || {\n            let _ = child.wait();\n        });\n    Ok(())\n}\n\n#[cfg(all(target_os = \"linux\", not(target_env = \"ohos\"), not(test)))]\nfn write_text_with_wlcopy(text: &str) -> Result<()> {\n    write_text_with_wlcopy_using_argv(\"wl-copy\", text)\n}\n\n#[cfg(all(target_os = \"linux\", not(target_env = \"ohos\"), not(test)))]\nfn read_text_with_wlpaste() -> Result<String> {\n    read_text_with_wlpaste_using_argv(\"wl-paste\")\n}","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tui/clipboard.rs#L523-L559","documentation":"Writing the payload to the clipboard helper's piped stdin failed in write_text_with_stdin_command. In practice this is almost always BrokenPipe (EPIPE): the helper (pbcopy or powershell.exe) exited before consuming the input, closing the pipe while write_all was still pushing bytes. It can also fire when the helper is killed mid-write.","triggerScenarios":"child.stdin.write_all returns Err(BrokenPipe): powershell.exe aborts immediately (execution policy, constrained language mode, profile error), pbcopy crashes on startup under sandbox restrictions, or the helper is OOM-killed while the TUI writes a large payload.","commonSituations":"PowerShell execution policy blocking Set-Clipboard; macOS Seatbelt denying pbcopy; very large payloads racing a fast-exiting helper.","solutions":["Test the helper standalone: `echo hi | pbcopy` (macOS) or `echo hi | powershell.exe -NoProfile -Command Set-Clipboard` (Windows)","For PowerShell failures check execution policy: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned","Treat EPIPE as 'helper refused' and let the caller fall through to the OSC 52/tmux path (the built-in behavior)","Keep payloads moderate so the helper is not overrun before it starts reading"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Rust - confirm the helper accepts input before routing the real payload\nfn helper_accepts_stdin(program: &str, args: &[&str]) -> bool {\n    std::process::Command::new(program)\n        .args(args)\n        .stdin(std::process::Stdio::piped())\n        .stdout(std::process::Stdio::null())\n        .stderr(std::process::Stdio::null())\n        .spawn()\n        .and_then(|mut c| { if let Some(mut s) = c.stdin.take() { s.write_all(b\"\")?; } c.wait() })\n        .map(|st| st.success())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match write_text_with_stdin_command(prog, args, text, label) {\n    Err(e) if e.to_string().contains(\"Broken pipe\") || e.to_string().contains(\"broken pipe\") => {\n        try_terminal_client_fallback(); // helper refused; do not retry the same helper\n    }\n    other => other,\n}","preventionTips":["Verify helpers standalone (`echo hi | pbcopy`) after policy/sandbox changes","Keep payloads moderate so helpers can start reading before the pipe fills","Watch PowerShell execution-policy changes that kill Set-Clipboard at startup"],"tags":["clipboard","broken-pipe","stdin","subprocess"],"backgroundTag":"broken-pipe","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}