{"record":{"id":"f799d38f68fa8ae8","repo":"chenhg5/cc-connect","slug":"send-s","errorCode":null,"errorMessage":"send: %s","messagePattern":"send: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/copilot/session.go","lineNumber":734,"sourceCode":"\tif sid == \"\" {\n\t\treturn fmt.Errorf(\"no active session\")\n\t}\n\n\tparams := map[string]any{\n\t\t\"sessionId\": sid,\n\t\t\"prompt\":    prompt,\n\t}\n\n\t_, sendCh := cs.rpc.call(\"session.send\", params)\n\n\t// Don't block - just validate the send was accepted\n\tgo func() {\n\t\tselect {\n\t\tcase resp := <-sendCh:\n\t\t\tif resp.Error != nil {\n\t\t\t\tslog.Error(\"copilotSession: send failed\", \"error\", resp.Error)\n\t\t\t\tif cs.alive.Load() {\n\t\t\t\t\tevt := core.Event{Type: core.EventError, Error: fmt.Errorf(\"send: %s\", resp.Error.Message)}\n\t\t\t\t\tselect {\n\t\t\t\t\tcase cs.events <- evt:\n\t\t\t\t\tcase <-cs.ctx.Done():\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tslog.Debug(\"copilotSession: send accepted\")\n\t\t\t}\n\t\tcase <-cs.ctx.Done():\n\t\t}\n\t}()\n\n\treturn nil\n}\n\n// RespondPermission sends a permission decision back to the Copilot process.\n// If the permission request came as a server-to-client RPC request (has a JSON-RPC id),\n// a proper JSON-RPC response is sent; otherwise a notification is used.","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/copilot/session.go#L716-L752","documentation":"When the 'session.send' JSON-RPC call returns an error response while the process is still alive, copilotSession logs it and emits a core.EventError carrying fmt.Errorf(\"send: %s\", resp.Error.Message). The visible message is 'send: <CLI error text>', meaning the Copilot process is running but rejected the prompt delivery.","triggerScenarios":"Send -> goroutine waiting on sendCh receives resp with resp.Error != nil and cs.alive is true -> event pushed to cs.events. Produced by the CLI rejecting the send: invalid/expired sessionId, prompt rejected by the backend, or an internal CLI error while processing the prompt.","commonSituations":"Session ID invalidated server-side or by a CLI restart while cc-connect still holds it; Copilot backend quota/auth failure surfacing through the CLI; prompt too large or containing unsupported content; transient CLI-internal error mid-conversation.","solutions":["Read the text after 'send: ' in the event — the CLI's own error message identifies the real cause.","Start a fresh session (/new) to obtain a valid sessionId, then resend the prompt.","Re-authenticate the Copilot CLI if the message indicates auth/quota problems.","Retry the send once for transient errors before restructuring the prompt.","Trim the prompt/attachments if the error indicates size or content rejection.","The event is delivered on the event stream, so handle core.EventError by notifying the user instead of crashing the pipeline."],"exampleFix":"// before: resending into a stale session after CLI restart\nsession.Send(prompt, id, nil, nil) // event: send: session not found\n// after: recreate the session when send reports an invalid session\n// (user action) /new  -> then resend the prompt","handlingStrategy":"try-catch","validationCode":"if session.CurrentSessionID() == \"\" || !sessionAlive(session) {\n    return fmt.Errorf(\"cannot send: session invalid or process dead\")\n}","typeGuard":null,"tryCatchPattern":"for evt := range session.Events() {\n    if evt.Type == core.EventError && strings.HasPrefix(evt.Error.Error(), \"send: \") {\n        cause := strings.TrimPrefix(evt.Error.Error(), \"send: \")\n        if strings.Contains(cause, \"session\") { // e.g. session not found\n            session = agent.StartSession(ctx, opts) // fresh sessionId, resend\n        }\n    }\n}","preventionTips":["Always read the text after 'send: ' — it is the CLI's own diagnosis","Recreate the session when the CLI reports the sessionId is invalid","Handle core.EventError on the stream so users see send failures","Keep the CLI authenticated to avoid quota/auth send rejections","Retry transient failures once before recreating the session"],"tags":["send","rpc","json-rpc","event-stream","upstream-error"],"backgroundTag":"api-request-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"}