Skip to content

Commit dccd8a7

Browse files
Fix Go stderr capture on Unix: use cmd.Stderr instead of StderrPipe
StderrPipe gets closed by cmd.Wait() before io.Copy can finish reading. Using cmd.Stderr = &buffer ensures all stderr is captured before Wait returns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3e74ff4 commit dccd8a7

File tree

1 file changed

+2
-15
lines changed

1 file changed

+2
-15
lines changed

go/client.go

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"encoding/json"
3535
"errors"
3636
"fmt"
37-
"io"
3837
"net"
3938
"os"
4039
"os/exec"
@@ -1093,18 +1092,8 @@ func (c *Client) startCLIServer(ctx context.Context) error {
10931092
return fmt.Errorf("failed to create stdout pipe: %w", err)
10941093
}
10951094

1096-
stderr, err := c.process.StderrPipe()
1097-
if err != nil {
1098-
return fmt.Errorf("failed to create stderr pipe: %w", err)
1099-
}
1100-
1101-
// Read stderr in background, capturing for error messages
1102-
var stderrWg sync.WaitGroup
1103-
stderrWg.Add(1)
1104-
go func() {
1105-
defer stderrWg.Done()
1106-
io.Copy(&c.stderrBuf, stderr)
1107-
}()
1095+
// Capture stderr directly to buffer (not via pipe, which gets closed on Wait())
1096+
c.process.Stderr = &c.stderrBuf
11081097

11091098
if err := c.process.Start(); err != nil {
11101099
return fmt.Errorf("failed to start CLI server: %w", err)
@@ -1114,8 +1103,6 @@ func (c *Client) startCLIServer(ctx context.Context) error {
11141103
c.processDone = make(chan struct{})
11151104
go func() {
11161105
err := c.process.Wait()
1117-
// Wait for stderr to be fully read before checking the buffer
1118-
stderrWg.Wait()
11191106
stderrOutput := strings.TrimSpace(c.stderrBuf.String())
11201107
if stderrOutput != "" {
11211108
c.processError = fmt.Errorf("CLI process exited: %v\nstderr: %s", err, stderrOutput)

0 commit comments

Comments
 (0)