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

  1. Print the raw result to compare against getSessionMetadataResponse fields
  2. Verify the session exists via ListSessions before fetching metadata
  3. Align client and backend versions
  4. 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

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


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)