{"record":{"id":"d43c6c66c8b6acc1","repo":"rtk-ai/rtk","slug":"stdout-streaming-thread-panicked","errorCode":null,"errorMessage":"stdout streaming thread panicked","messagePattern":"stdout streaming thread panicked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":3175,"sourceCode":"                    }\n                    let mut err = std::io::stderr().lock();\n                    err.write_all(&buf[..count])?;\n                    err.flush()?;\n                }\n\n                Ok(captured)\n            });\n\n            let status = child\n                .0\n                .take()\n                .context(\"Child process missing\")?\n                .wait()\n                .context(format!(\"Failed waiting for command: {}\", cmd_name))?;\n\n            let stdout_bytes = stdout_handle\n                .join()\n                .map_err(|_| anyhow::anyhow!(\"stdout streaming thread panicked\"))??;\n            let stderr_bytes = stderr_handle\n                .join()\n                .map_err(|_| anyhow::anyhow!(\"stderr streaming thread panicked\"))??;\n\n            let stdout = core::utils::decode_process_output(&stdout_bytes);\n            let stderr = core::utils::decode_process_output(&stderr_bytes);\n            let full_output = format!(\"{}{}\", stdout, stderr);\n\n            // Track usage (input = output since no filtering)\n            timer.track(\n                &format!(\"{} {}\", cmd_name, cmd_args.join(\" \")),\n                &format!(\"rtk proxy {} {}\", cmd_name, cmd_args.join(\" \")),\n                &full_output,\n                &full_output,\n            );\n\n            core::utils::exit_code_from_status(&status, &cmd_name)\n        }","sourceCodeStart":3157,"sourceCodeEnd":3193,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/main.rs#L3157-L3193","documentation":"In rtk's unfiltered proxy path, stdout of the spawned child is drained by a dedicated thread that streams bytes into a buffer. After `child.wait()` completes, main.rs joins that thread's JoinHandle; if the thread panicked (the handle returns Err), it maps the panic to `anyhow!(\"stdout streaming thread panicked\")`. This indicates an internal reader-thread failure, not a failure of the proxied command itself.","triggerScenarios":"The stdout reader thread spawned in the proxy execution path panics while reading from the child's piped stdout (e.g. I/O read error on the pipe or an unwrap inside the thread), so `stdout_handle.join()` at src/main.rs:3175 returns Err and is converted into this anyhow error.","commonSituations":"Child process closes/steals its own stdout pipe abnormally; OS-level pipe errors under resource exhaustion (fd limits, OOM killer hitting the thread); a bug in the reader thread's unwrapping logic on unusual byte streams.","solutions":["Re-run the command with `rtk proxy` retried once — transient pipe errors often disappear.","Run the underlying command directly (outside rtk) to confirm the command itself works; if it does, report the rtk bug with the repro command.","Check system resource limits (`ulimit -n`, memory) that could break pipe reads in the streaming thread.","Update rtk to the latest version, as streaming-thread panics are typically internal bugs fixed upstream."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"rtk proxy <cmd> || {\n  # fall back to running the command directly\n  <cmd>\n}","preventionTips":["Keep system fd/memory limits healthy for long streaming pipelines.","Avoid child commands that close or rewire their own stdout.","On recurrence, bypass with `rtk proxy` semantics removed (run raw) and report the bug upstream."],"tags":["proxy-mode","thread-panic","stdout","process-piping"],"backgroundTag":"thread-interrupted","analyzedSha":"0924356b4caba4989607227b7c8824d3d8098719","analyzedAt":"2026-09-19T19:25:29.612Z","contentChangedAt":"2026-09-19T19:25:29.612Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}