{"record":{"id":"c934a2f88f7bf41f","repo":"chenhg5/cc-connect","slug":"ping-w","errorCode":null,"errorMessage":"ping: %w","messagePattern":"ping: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/copilot/session.go","lineNumber":165,"sourceCode":"\t// Start reading loop\n\tgo cs.readLoop(&stderrBuf)\n\n\t// Perform handshake: ping then create/resume session\n\tif err := cs.handshake(resumeSessionID); err != nil {\n\t\t_ = cs.Close()\n\t\treturn nil, fmt.Errorf(\"copilotSession: handshake failed: %w\", err)\n\t}\n\n\treturn cs, nil\n}\n\nfunc (cs *copilotSession) handshake(resumeSessionID string) error {\n\t// Step 1: Ping\n\t_, pingCh := cs.rpc.call(\"ping\", nil)\n\tselect {\n\tcase resp := <-pingCh:\n\t\tif resp.Error != nil {\n\t\t\treturn fmt.Errorf(\"ping: %w\", resp.Error)\n\t\t}\n\t\tslog.Debug(\"copilotSession: ping OK\")\n\tcase <-time.After(10 * time.Second):\n\t\treturn fmt.Errorf(\"ping timeout\")\n\tcase <-cs.ctx.Done():\n\t\treturn cs.ctx.Err()\n\t}\n\n\t// Step 2: Create or resume session\n\tif resumeSessionID != \"\" && resumeSessionID != core.ContinueSession {\n\t\t_, resumeCh := cs.rpc.call(\"session.resume\", cs.sessionConfig(resumeSessionID))\n\t\tselect {\n\t\tcase resp := <-resumeCh:\n\t\t\tif resp.Error != nil {\n\t\t\t\tslog.Warn(\"copilotSession: resume failed, creating new session\", \"error\", resp.Error)\n\t\t\t\treturn cs.createSession()\n\t\t\t}\n\t\t\tcs.sessionID.Store(resumeSessionID)","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/copilot/session.go#L147-L183","documentation":"Handshake step 1 sends the JSON-RPC `ping` request to the copilot process. If the process replies with a JSON-RPC error object, it is surfaced as \"ping: %w\". The session is functional at the transport level but the CLI refused the ping — usually an authentication, version, or internal CLI problem.","triggerScenarios":"handshake() called from newCopilotSession: rpc.call(\"ping\", nil) completes but resp.Error != nil — the copilot CLI returned an error result for the ping method (e.g. not initialized, unauthorized, method unsupported).","commonSituations":"Older copilot CLI versions without ping support; CLI requiring initialization before accepting requests; expired Copilot authentication; CLI reporting an internal error on startup.","solutions":["Read the wrapped JSON-RPC error message/data for the exact reason the CLI rejected ping","Re-authenticate: run `copilot auth login` (or equivalent) as the daemon user","Update the copilot CLI to a version that supports the ping method","If the CLI requires an initialize step first, ensure the handshake order matches the CLI's protocol version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"sess, err := StartSession(ctx, cfg, resumeID)\nif err != nil {\n    var rpcErr interface{ Error() string }\n    if strings.Contains(err.Error(), \"ping:\") {\n        // JSON-RPC error from the CLI — usually auth/version; surface inner message\n        slog.Error(\"copilot: ping rejected\", \"cause\", err)\n        return fmt.Errorf(\"copilot unavailable: %w\", err)\n    }\n    return err\n}","preventionTips":["Re-run CLI login whenever Copilot auth expires (periodic credential refresh)","Match the handshake sequence to the CLI version's protocol","Watch the CLI changelog for method renames like ping/session.create","Surface the inner JSON-RPC message to logs, not just the wrapper"],"tags":["jsonrpc","ping","copilot","rpc-error"],"backgroundTag":"upstream-api-error","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}