github/copilot-sdk · error
failed to unmarshal session metadata response
Error message
failed to unmarshal session metadata response: %w
What it means
GetSessionMetadata returns this error when the 'session.getMetadata' result fails to decode into getSessionMetadataResponse. It indicates the backend's metadata payload did not match the expected struct, with the decode error wrapped for diagnosis.
Solutions
- Print the raw result to compare against getSessionMetadataResponse fields
- Verify the session exists via ListSessions before fetching metadata
- Align client and backend versions
- If the session was created by a different product version, recreate or migrate it
Example fix
// before
meta, err := client.GetSessionMetadata(ctx, id)
// after
meta, err := client.GetSessionMetadata(ctx, id)
if err != nil {
if strings.Contains(err.Error(), "unmarshal session metadata") {
log.Printf("unexpected metadata shape for %s: %v", id, err)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
if sessionID == "" {
return nil, fmt.Errorf("GetSessionMetadata: empty sessionID")
} Type guard
func isMetadataUnmarshalError(err error) bool {
return strings.Contains(err.Error(), "unmarshal session metadata response")
} Try / catch
meta, err := client.GetSessionMetadata(ctx, id)
if err != nil {
if isMetadataUnmarshalError(err) {
// fall back to partial info from ListSessions
return nil, fmt.Errorf("metadata for %s undecodable: %w", id, err)
}
return nil, err
} Prevention
- Verify the session exists before fetching metadata
- Avoid mixing sessions created across incompatible product versions
- Log raw payloads in debug builds
When it happens
Trigger: Calling GetSessionMetadata with a sessionID whose backend response shape differs from getSessionMetadataResponse (wrong field types, missing session object).
Common situations: Querying a session created by a newer/older backend version with extra or renamed metadata fields; stale session data on disk.
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.
Related errors
- failed to unmarshal response
- failed to unmarshal sessions response
- failed to unmarshal delete response
- failed to unmarshal getLastId response
- failed to unmarshal getForeground response
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5ad201425f45018f.
Report an issue: GitHub.
Appendix: source
Thrown at go/client.go:1584
// if err != nil {
// log.Fatal(err)
// }
// if metadata != nil {
// fmt.Printf("Session started at: %s\n", metadata.StartTime)
// }
func (c *Client) GetSessionMetadata(ctx context.Context, sessionID string) (*SessionMetadata, error) {
if err := c.ensureConnected(ctx); err != nil {
return nil, err
}
result, err := c.client.Request(ctx, "session.getMetadata", getSessionMetadataRequest{SessionID: sessionID})
if err != nil {
return nil, err
}
var response getSessionMetadataResponse
if err := json.Unmarshal(result, &response); err != nil {
return nil, fmt.Errorf("failed to unmarshal session metadata response: %w", err)
}
return response.Session, nil
}
// DeleteSession permanently deletes a session and all its data from disk,
// including conversation history, planning state, and artifacts.
//
// Unlike [Session.Disconnect], which only releases in-memory resources and
// preserves session data for later resumption, DeleteSession is irreversible.
// The session cannot be resumed after deletion. If the session is in the local
// sessions map, it will be removed.
//
// Example:
//
// if err := client.DeleteSession(context.Background(), "session-123"); err != nil {
// log.Fatal(err)
// }View on GitHub (pinned to cd8cf15dc3)