{"record":{"id":"1b2c0d00f8f482f5","repo":"github/copilot-sdk","slug":"failed-to-connect-to-cli-server-at-s-w","errorCode":null,"errorMessage":"failed to connect to CLI server at %s: %w","messagePattern":"failed to connect to CLI server at (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/client.go","lineNumber":2446,"sourceCode":"\t// Connect via TCP\n\treturn c.connectViaTCP(ctx)\n}\n\n// connectViaTCP connects to the CLI server via TCP socket.\nfunc (c *Client) connectViaTCP(ctx context.Context) error {\n\tif c.actualPort == 0 {\n\t\treturn fmt.Errorf(\"server port not available\")\n\t}\n\n\t// Merge a 10-second timeout with the caller's context so whichever\n\t// deadline comes first wins.\n\taddress := net.JoinHostPort(c.actualHost, fmt.Sprintf(\"%d\", c.actualPort))\n\tdialCtx, cancel := context.WithTimeout(ctx, 10*time.Second)\n\tdefer cancel()\n\tvar dialer net.Dialer\n\tconn, err := dialer.DialContext(dialCtx, \"tcp\", address)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to connect to CLI server at %s: %w\", address, err)\n\t}\n\n\tc.conn = conn\n\n\t// Create JSON-RPC client with the connection\n\tc.client = jsonrpc2.NewClient(conn, conn)\n\tif c.processDone != nil {\n\t\tc.client.SetProcessDone(c.processDone, c.processErrorPtr)\n\t}\n\tc.client.SetOnClose(c.handleConnectionClose)\n\tc.RPC = rpc.NewServerRPC(c.client)\n\tc.internalRPC = rpc.NewInternalServerRPC(c.client)\n\tc.setupNotificationHandler()\n\tc.client.Start()\n\n\treturn nil\n}\n","sourceCodeStart":2428,"sourceCodeEnd":2464,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/client.go#L2428-L2464","documentation":"Returned by connectViaTCP when the TCP dial to host:port fails within the 10-second dial timeout. The original dial error (refused, timeout, unreachable, DNS failure) is wrapped, so %w carries the precise cause.","triggerScenarios":"Client.connectViaTCP dialing net.JoinHostPort(actualHost, actualPort) fails: server not listening on that port, wrong host, firewall, or the 10s context deadline expires before the handshake completes.","commonSituations":"CLI server crashed or was never started; port number stale after server restart; connecting to a container/remote host where the port isn't exposed; IPv4/IPv6 mismatch on 'localhost'; corporate firewall blocking the port.","solutions":["Verify the CLI server process is running and listening on the reported port (e.g. lsof -i :PORT, or `nc -zv host port`).","Check the host value: use 127.0.0.1 instead of localhost to rule out IPv6 resolution issues.","Confirm firewalls/security groups allow TCP traffic to the port, especially for remote/container targets.","Re-read the server's current port (it may change per launch) and retry with the fresh value.","Inspect the wrapped error to distinguish connection refused (not listening) from timeout (firewall/routing)."],"exampleFix":"// before\nc := client.New(client.WithHost(\"localhost\"), client.WithPort(8080))\n\n// after\nif err := net.DialTimeout(\"tcp\", \"127.0.0.1:8080\", 2*time.Second); err != nil {\n    log.Fatalf(\"CLI server not reachable, is it running? %v\", err)\n}\nc := client.New(client.WithHost(\"127.0.0.1\"), client.WithPort(8080))","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", addr, 2*time.Second)\nif err != nil { return fmt.Errorf(\"server not reachable at %s: %w\", addr, err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff or check firewall\n    }\n    return err\n}","preventionTips":["Health-check the host:port with a quick dial before connecting.","Prefer 127.0.0.1 over localhost to avoid IPv6 resolution surprises.","Re-read the server port after every server restart.","Confirm firewall/security-group rules for remote targets."],"tags":["network","tcp","connection","go"],"backgroundTag":"connection-refused","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}