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
- Log the raw response body (raw json.RawMessage) to see what the server actually returned
- Verify the endpoint is the real agent server and no proxy/auth redirect is intercepting the request
- Check server version compatibility with this client SDK and upgrade/pin accordingly
- 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
- Log raw response bodies in development
- Bypass or authenticate proxies in the request path
- Pin server and SDK versions
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to unmarshal send response
- No session found for sessionId
- session.create response did not include a sessionId
- session.create returned sessionId
- Failed to delete session
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)