github/copilot-sdk · error

failed to parse sessionId from response

Error message

failed to parse sessionId from response: %w

What it means

When a session is created inline (session == nil), the client parses the session.create response body to extract the server-assigned sessionId. This error wraps a json.Unmarshal failure on that raw response payload, meaning the server returned something that is not valid JSON or not shaped as expected. It indicates a protocol/response-format problem rather than a caller mistake.

Solutions

  1. Log the raw response body (raw json.RawMessage) to see what the server actually returned
  2. Verify the endpoint is the real agent server and no proxy/auth redirect is intercepting the request
  3. Check server version compatibility with this client SDK and upgrade/pin accordingly
  4. Inspect network path (VPN, corporate proxy) that could rewrite response bodies

Example fix

// before: opaque parse failure
s, err := c.CreateSession(ctx, opts)
// after: surface the underlying payload
if err != nil && strings.Contains(err.Error(), "failed to parse sessionId") {
    log.Printf("session.create raw response: %s", debugRawBody)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if resp.StatusCode != 200 || !strings.Contains(resp.Header.Get("Content-Type"), "json") {
    return fmt.Errorf("unexpected session.create response: %s %s", resp.Status, resp.Header.Get("Content-Type"))
}

Type guard

func looksLikeJSON(b []byte) bool { t := bytes.TrimSpace(b); return len(t) > 0 && (t[0] == '{' || t[0] == '[') }

Try / catch

s, err := client.CreateSession(ctx, opts)
if err != nil {
    if strings.Contains(err.Error(), "failed to parse sessionId") {
        // inspect raw payload / proxy path, do not retry blindly
        return handleProtocolError(err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling CreateSession when the underlying RequestWithInlineResponse("session.create") returns a raw payload that fails json.Unmarshal into the {"sessionId": string} probe struct — e.g. a proxy or dev server returning HTML error pages, truncated bodies, or non-JSON content types.

Common situations: Reverse proxies/auth walls returning HTML login pages; gateway 502 bodies intercepted as raw messages; a server version emitting a non-object (array or string) JSON body; TLS-terminated endpoints returning compression-garbled output.

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/1a4418eb92a0f7b1. Report an issue: GitHub.

Appendix: source

Thrown at go/client.go:1124

		session = s
		registeredSessionID = localSessionID
	}

	// For the server-assigned (cloud) path, register the session
	// synchronously from the read loop the instant the response arrives,
	// before the read loop dispatches the next message. Without this hook
	// the awaiter goroutine may not run until after the read loop has
	// dispatched the first session.event notification, which would be
	// silently dropped because the session id isn't yet in the lookup
	// table. Non-cloud sessions are already registered above.
	var inlineCb func(raw json.RawMessage) error
	if session == nil {
		inlineCb = func(raw json.RawMessage) error {
			var early struct {
				SessionID string `json:"sessionId"`
			}
			if err := json.Unmarshal(raw, &early); err != nil {
				return fmt.Errorf("failed to parse sessionId from response: %w", err)
			}
			if early.SessionID == "" {
				return fmt.Errorf("session.create response did not include a sessionId")
			}
			s, err := initializeSession(early.SessionID)
			if err != nil {
				return err
			}
			session = s
			registeredSessionID = early.SessionID
			return nil
		}
	}

	result, err := c.client.RequestWithInlineResponse(ctx, "session.create", req, inlineCb)
	if err != nil {
		if registeredSessionID != "" {
			unregisterSession(registeredSessionID, session)

View on GitHub (pinned to cd8cf15dc3)