chenhg5/cc-connect · error

send: %s

Error message

send: %s

What it means

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.

Source

Thrown at agent/copilot/session.go:734

	if sid == "" {
		return fmt.Errorf("no active session")
	}

	params := map[string]any{
		"sessionId": sid,
		"prompt":    prompt,
	}

	_, sendCh := cs.rpc.call("session.send", params)

	// Don't block - just validate the send was accepted
	go func() {
		select {
		case resp := <-sendCh:
			if resp.Error != nil {
				slog.Error("copilotSession: send failed", "error", resp.Error)
				if cs.alive.Load() {
					evt := core.Event{Type: core.EventError, Error: fmt.Errorf("send: %s", resp.Error.Message)}
					select {
					case cs.events <- evt:
					case <-cs.ctx.Done():
					}
				}
			} else {
				slog.Debug("copilotSession: send accepted")
			}
		case <-cs.ctx.Done():
		}
	}()

	return nil
}

// RespondPermission sends a permission decision back to the Copilot process.
// If the permission request came as a server-to-client RPC request (has a JSON-RPC id),
// a proper JSON-RPC response is sent; otherwise a notification is used.

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the text after 'send: ' in the event — the CLI's own error message identifies the real cause.
  2. Start a fresh session (/new) to obtain a valid sessionId, then resend the prompt.
  3. Re-authenticate the Copilot CLI if the message indicates auth/quota problems.
  4. Retry the send once for transient errors before restructuring the prompt.
  5. Trim the prompt/attachments if the error indicates size or content rejection.
  6. The event is delivered on the event stream, so handle core.EventError by notifying the user instead of crashing the pipeline.

Example fix

// before: resending into a stale session after CLI restart
session.Send(prompt, id, nil, nil) // event: send: session not found
// after: recreate the session when send reports an invalid session
// (user action) /new  -> then resend the prompt
Defensive patterns

Strategy: try-catch

Validate before calling

if session.CurrentSessionID() == "" || !sessionAlive(session) {
    return fmt.Errorf("cannot send: session invalid or process dead")
}

Try / catch

for evt := range session.Events() {
    if evt.Type == core.EventError && strings.HasPrefix(evt.Error.Error(), "send: ") {
        cause := strings.TrimPrefix(evt.Error.Error(), "send: ")
        if strings.Contains(cause, "session") { // e.g. session not found
            session = agent.StartSession(ctx, opts) // fresh sessionId, resend
        }
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/f799d38f68fa8ae8. Report an issue: GitHub.