github/copilot-sdk · error
unknown error
Error message
unknown error
What it means
This error is returned when a session detach RPC completes but the runtime reports failure without including an error message in its response. The SDK substitutes the placeholder string "unknown error" because the remote side did not populate the Error field. It surfaces from Session.OnClose or Session.OnAction handlers when the underlying detach/canvas operation fails server-side with no detail.
Solutions
- Inspect runtime/server logs to find the real failure cause, since the SDK could not extract an error message.
- Retry the operation to rule out a transient runtime failure.
- Verify runtime and SDK versions are compatible.
- If persistent, report to the runtime maintainers that the error field is unpopulated.
Example fix
// before
err := handler.OnClose(ctx, req) // yields 'unknown error'
// after
if err != nil && err.Error() == "unknown error" {
log.Printf("detach failed with no server detail; check runtime logs")
} Defensive patterns
Strategy: try-catch
Validate before calling
if resp.Success == false && resp.Error == "" { log.Printf("server failed with no detail") } Try / catch
if err != nil { if err.Error() == "unknown error" { /* inspect server logs, retry */ } } Prevention
- Log full RPC responses to capture missing error detail
- Monitor runtime health before operations
- Pin compatible SDK/runtime versions
When it happens
Trigger: Calling a CanvasHandler OnClose or OnAction whose underlying session detach RPC returns success=false with an empty response.Error string.
Common situations: Runtime process crashed mid-request; server returned a malformed or empty error field; protocol version mismatch causing the error detail to be dropped.
Related errors
- failed to get events
- failed to disconnect session
- failed to abort session
- failed to log message
- No session found for sessionId
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/6103614e1b1eb4c4.
Report an issue: GitHub.
Appendix: source
Thrown at go/session.go:1846
//
// 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()
s.toolHandlersM.Lock()
s.toolHandlers = nil
s.toolHandlersM.Unlock()
View on GitHub (pinned to cd8cf15dc3)