github/copilot-sdk · warning

failed to close socket

Error message

failed to close socket: %w

What it means

When the client was created against an external server over TCP, Stop closes that socket; a Close failure is wrapped with this message and appended to Stop's error list. It indicates the TCP connection could not be closed cleanly.

Solutions

  1. Check the wrapped cause; 'use of closed connection' errors are harmless — treat Stop as complete.
  2. Avoid calling Stop twice on the same client.
  3. Verify the external server is reachable and behaving during teardown.
  4. If persistent, inspect network/firewall configuration.

Example fix

// before
err := client.Stop(ctx); // may surface socket close error
// after
if err != nil && strings.Contains(err.Error(), "failed to close socket") {
    log.Printf("socket close issue during stop (often harmless): %v", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := client.Stop(ctx); err != nil && strings.Contains(err.Error(), "failed to close socket") { /* usually benign */ }

Prevention

When it happens

Trigger: Calling Stop on a client configured with isExternalServer whose c.conn.Close() returns an error (e.g. already closed, reset by peer).

Common situations: External runtime already dropped the connection; double Stop calls; firewall/network teardown mid-close.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/410f4529b145866b. Report an issue: GitHub.

Appendix: source

Thrown at go/client.go:640

	// immediately and only wait to reap it.
	if c.process != nil && !c.isExternalServer {
		if err := c.killProcessAndWait(); err != nil {
			errs = append(errs, err)
		}
	}
	c.process = nil

	// Tear down the in-process FFI host (closes the connection and shuts down the
	// native runtime). No child process to reap in this mode.
	if c.ffiHost != nil {
		c.ffiHost.Dispose()
		c.ffiHost = nil
	}

	// Close external TCP connection if exists
	if c.isExternalServer && c.conn != nil {
		if err := c.conn.Close(); err != nil {
			errs = append(errs, fmt.Errorf("failed to close socket: %w", err))
		}
		c.conn = nil
	}

	// Then close JSON-RPC client (readLoop can now exit)
	if c.client != nil {
		c.client.Stop()
		c.client = nil
	}

	// Clear models cache
	c.modelsCacheMux.Lock()
	c.modelsCache = nil
	c.modelsCacheMux.Unlock()

	c.state = stateDisconnected
	if !c.isExternalServer {
		c.actualPort = 0

View on GitHub (pinned to cd8cf15dc3)