{"record":{"id":"9f2af0ee12105b6f","repo":"github/copilot-sdk","slug":"failed-to-disconnect-session-s-w","errorCode":null,"errorMessage":"failed to disconnect session %s: %w","messagePattern":"failed to disconnect session (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"go/client.go","lineNumber":583,"sourceCode":"// Example:\n//\n//\tif err := client.Stop(); err != nil {\n//\t    log.Printf(\"Cleanup error: %v\", err)\n//\t}\nfunc (c *Client) Stop() error {\n\tvar errs []error\n\n\t// Disconnect all active sessions\n\tc.sessionsMux.Lock()\n\tsessions := make([]*Session, 0, len(c.sessions))\n\tfor _, session := range c.sessions {\n\t\tsessions = append(sessions, session)\n\t}\n\tc.sessionsMux.Unlock()\n\n\tfor _, session := range sessions {\n\t\tif err := session.Disconnect(); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"failed to disconnect session %s: %w\", session.SessionID, err))\n\t\t}\n\t}\n\n\tc.sessionsMux.Lock()\n\tc.sessions = make(map[string]*Session)\n\tc.sessionsMux.Unlock()\n\tc.clearGitHubTokenProviders()\n\n\tc.startStopMux.Lock()\n\tdefer c.startStopMux.Unlock()\n\n\tif (c.process != nil || c.ffiHost != nil) && !c.isExternalServer && c.RPC != nil {\n\t\trpcClient := c.RPC\n\t\truntimeShutdownStart := time.Now()\n\t\tshutdownDone := make(chan error, 1)\n\t\tgo func() {\n\t\t\t_, err := rpcClient.Runtime.Shutdown(context.Background())\n\t\t\tshutdownDone <- err","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/client.go#L565-L601","documentation":"CopilotClient.Stop disconnects every registered session and wraps each Session.Disconnect failure with the session's ID. The wrapped error indicates one specific session failed to clean up while the overall Stop still proceeds over the other sessions.","triggerScenarios":"Calling Stop (or ForceStop) when one or more sessions' Disconnect RPC fails, e.g. because the runtime connection is already broken.","commonSituations":"Network drop before Stop; runtime process already exited; duplicate Stop calls where the second finds dead connections.","solutions":["Inspect the wrapped inner error and session ID to identify which session failed.","Check that the runtime process/connection is healthy before stopping.","Treat Stop as best-effort: resources are cleared from the client's session map regardless.","Retry Stop only if the inner error indicates a transient network issue."],"exampleFix":"// before\nif err := client.Stop(ctx); err != nil { panic(err) }\n// after\nif err := client.Stop(ctx); err != nil {\n    log.Printf(\"stop partially failed (resources still cleaned up): %v\", err)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := client.Stop(ctx); err != nil { for _, e := range unwrapAll(err) { log.Printf(\"session stop issue: %v\", e) } }","preventionTips":["Keep runtime connection healthy before Stop","Avoid duplicate Stop calls","Treat Stop errors as best-effort cleanup notices"],"tags":["go","session","shutdown"],"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"}