github/copilot-sdk · error
failed to decode session detach response
Error message
failed to decode session detach response: %w
What it means
Session.Disconnect sends the `session.detach` RPC; on success it unmarshals the result into sessionDetachResponse. This error means the detach response JSON could not be decoded — the runtime's reply does not match the SDK's expected `{success, error}` shape.
Solutions
- Align SDK and runtime versions (upgrade both)
- Capture the raw detach response to compare against the expected shape
- Retry Disconnect once; if it persists, close the underlying client connection instead
- File an issue with the raw payload if versions already match
Example fix
// before
if err := session.Disconnect(); err != nil { log.Fatal(err) }
// after
if err := session.Disconnect(); err != nil {
log.Printf("detach decode failed, forcing client close: %v", err)
_ = client.Close()
} Defensive patterns
Strategy: fallback
Try / catch
if err := session.Disconnect(); err != nil {
if strings.Contains(err.Error(), "decode session detach") {
_ = client.Close() // fall back to local teardown
} else {
return err
}
} Prevention
- Match SDK and runtime versions
- Never assume detach succeeded without checking err
- Have a local-cleanup fallback for teardown paths
When it happens
Trigger: Calling Session.Disconnect() when `session.detach` returns a payload that fails json.Unmarshal into sessionDetachResponse (wrong field types or unexpected schema).
Common situations: Version skew between SDK and runtime changing the detach response; a non-standard runtime build returning a different detach payload; truncated/corrupt response.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to unmarshal models response
- failed to unmarshal get events response
- failed to unmarshal schema for type
- unknown error
- failed to disconnect session
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/e4425fafcf6fe621.
Report an issue: GitHub.
Appendix: source
Thrown at go/session.go:1841
// session data including files on disk, use [Client.DeleteSession] instead.
//
// After calling this method, the session object can no longer be used.
//
// Returns an error if the connection fails.
//
// Example:
//
// // Clean up when done — session can still be resumed later
// if err := session.Disconnect(); err != nil {
// log.Printf("Failed to disconnect session: %v", err)
// }
func (s *Session) Disconnect() error {
s.cancelPendingExternalTools()
result, err := s.client.Request(context.Background(), "session.detach", sessionDetachRequest{SessionID: s.SessionID})
if err == nil {
var response sessionDetachResponse
if decodeErr := json.Unmarshal(result, &response); decodeErr != nil {
err = fmt.Errorf("failed to decode session detach response: %w", decodeErr)
} else if !response.Success {
if response.Error == "" {
response.Error = "unknown error"
}
err = errors.New(response.Error)
}
}
// Local cleanup always runs, even if the detach RPC failed, so callers
// don't leak in-memory resources (event goroutines, registered
// providers/handlers) just because the runtime couldn't be reached.
s.stopEventProcessing()
s.releaseGitHubTokenProviderRegistration()
// Clear handlers
s.handlerMutex.Lock()
s.handlers = nil
s.handlerMutex.Unlock()View on GitHub (pinned to cd8cf15dc3)