Skip to content

Go: stop RPC client logging expected errors#609

Open
chlowell wants to merge 1 commit intogithub:mainfrom
chlowell:go-closed-stdout
Open

Go: stop RPC client logging expected errors#609
chlowell wants to merge 1 commit intogithub:mainfrom
chlowell:go-closed-stdout

Conversation

@chlowell
Copy link
Contributor

You might see Error reading header: read |0: file already closed printed during client shutdown on Linux. This happens because copilot.Client kills the CLI subprocess and calls the RPC client's Stop method, which closes the subprocess's stdout. Meanwhile, the RPC client has a read loop blocked on a pipe connected to the subprocess's stdout. That loop breaks with an error: io.EOF if the process teardown wins the race, os.ErrClosed if the pipe close does. The comment anticipates this but the guard around printing the error expects only io.EOF. So, simple fix to avoid logging the expected error condition is to add os.ErrClosed to the guard.

Copilot AI review requested due to automatic review settings February 28, 2026 03:30
@chlowell chlowell requested a review from a team as a code owner February 28, 2026 03:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts Go’s internal JSON-RPC client shutdown behavior to avoid logging an expected “closed pipe/file already closed” read error during teardown, reducing noisy stderr output when copilot.Client stops the CLI subprocess.

Changes:

  • Add errors/os imports to support error classification.
  • Suppress logging for read-loop header errors when the underlying error is os.ErrClosed (in addition to io.EOF).

Comment on lines 310 to 314
// Only log unexpected errors (not EOF or closed pipe during shutdown)
if err != io.EOF && c.running.Load() {
if err != io.EOF && !errors.Is(err, os.ErrClosed) && c.running.Load() {
fmt.Printf("Error reading header: %v\n", err)
}
return
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readLoop now suppresses os.ErrClosed when failing to read the header, but the message-body read path still unconditionally logs Error reading body on shutdown. Since Stop() closes stdout specifically to unblock readLoop, io.ReadFull can also return os.ErrClosed/io.EOF during normal teardown and will still print an expected error. Consider applying the same “unexpected only” guard (including c.running.Load()) to the body read error handling so shutdown stays quiet regardless of whether the loop is in header or body read.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants