{"record":{"id":"e43db3c3d8194f8f","repo":"chenhg5/cc-connect","slug":"session-create-decode-w","errorCode":null,"errorMessage":"session.create decode: %w","messagePattern":"session\\.create decode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/copilot/session.go","lineNumber":207,"sourceCode":"\t\t}\n\t} else {\n\t\treturn cs.createSession()\n\t}\n\treturn nil\n}\n\nfunc (cs *copilotSession) createSession() error {\n\t_, createCh := cs.rpc.call(\"session.create\", cs.sessionConfig(newCopilotSessionID()))\n\tselect {\n\tcase resp := <-createCh:\n\t\tif resp.Error != nil {\n\t\t\treturn fmt.Errorf(\"session.create: %w\", resp.Error)\n\t\t}\n\t\tvar result struct {\n\t\t\tSessionID string `json:\"sessionId\"`\n\t\t}\n\t\tif err := json.Unmarshal(resp.Result, &result); err != nil {\n\t\t\treturn fmt.Errorf(\"session.create decode: %w\", err)\n\t\t}\n\t\tcs.sessionID.Store(result.SessionID)\n\t\tslog.Info(\"copilotSession: session created\", \"sessionId\", result.SessionID)\n\tcase <-time.After(10 * time.Second):\n\t\treturn fmt.Errorf(\"session.create timeout\")\n\tcase <-cs.ctx.Done():\n\t\treturn cs.ctx.Err()\n\t}\n\treturn nil\n}\n\nfunc (cs *copilotSession) sessionConfig(sessionID string) copilotSessionConfig {\n\trequestPermission := true\n\tstreaming := true\n\tincludeSubAgentStreaming := true\n\tenableConfigDiscovery := true\n\treturn copilotSessionConfig{\n\t\tSessionID:                      sessionID,","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/copilot/session.go#L189-L225","documentation":"After a successful 'session.create' RPC, createSession decodes the CLI's result payload expecting a JSON object with a 'sessionId' string field. If json.Unmarshal fails, the response was not the expected shape and the error is wrapped as 'session.create decode: %w'. This guards against protocol drift between cc-connect and the Copilot CLI.","triggerScenarios":"handshake -> createSession -> json.Unmarshal(resp.Result, &result) fails because the CLI returned a result payload without the expected {\"sessionId\": \"...\"} shape (protocol change, error payload in result position, empty/garbled JSON).","commonSituations":"Copilot CLI was updated and renamed/removed the sessionId result field; a proxy/wrapper prints extra output on stdout corrupting JSON-RPC framing; the CLI returned an error-shaped body inside Result.","solutions":["Check the installed Copilot CLI version and pin/upgrade cc-connect (or the CLI) so both sides agree on the session.create result schema.","Ensure nothing else writes to the child process's stdout (wrapper scripts, shell profiles echoing text).","Log resp.Result raw JSON at the failure point to see the actual payload and compare with the expected struct.","Retry once; a truncated pipe read can occasionally cause this.","File an issue with the raw payload if a version pair consistently fails."],"exampleFix":"// before: silent protocol mismatch\n// (CLI returns {\"id\": \"...\"} instead of {\"sessionId\": \"...\"})\n// after: pin a compatible CLI version\n// .github/workflows/ci.yml or install script\ncopilot --version # verify compatibility; install the version cc-connect documents","handlingStrategy":"type-guard","validationCode":"var probe map[string]any\nif err := json.Unmarshal(rawResult, &probe); err != nil {\n    return fmt.Errorf(\"session.create result not JSON: %w\", err)\n}\nif _, ok := probe[\"sessionId\"].(string); !ok {\n    return fmt.Errorf(\"session.create result missing sessionId\")\n}","typeGuard":"func hasSessionID(result json.RawMessage) bool {\n    var r struct{ SessionID string `json:\"sessionId\"` }\n    return json.Unmarshal(result, &r) == nil && r.SessionID != \"\"\n}","tryCatchPattern":"if err := agent.StartSession(ctx, opts); err != nil && strings.Contains(err.Error(), \"session.create decode\") {\n    slog.Error(\"protocol mismatch with copilot CLI\", \"err\", err)\n    // report version pair and fail fast\n}","preventionTips":["Pin compatible cc-connect + Copilot CLI version pairs","Ensure no wrapper scripts print extra text to the child's stdout","Log the raw JSON-RPC result on decode failure for diagnosis","Watch CLI release notes for session.create schema changes"],"tags":["json","unmarshal","protocol-mismatch","rpc"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}