chenhg5/cc-connect · error

session.resume timeout

Error message

session.resume timeout

What it means

During handshake, copilotSession tries to resume a previous Copilot CLI session via a 'session.resume' JSON-RPC call and waits on the response channel for at most 10 seconds. If the CLI process does not answer within that window, the handshake aborts with 'session.resume timeout' instead of blocking forever. The library throws this because an unresponsive child process would otherwise hang the whole agent session startup.

Source

Thrown at agent/copilot/session.go:186

	case <-time.After(10 * time.Second):
		return fmt.Errorf("ping timeout")
	case <-cs.ctx.Done():
		return cs.ctx.Err()
	}

	// Step 2: Create or resume session
	if resumeSessionID != "" && resumeSessionID != core.ContinueSession {
		_, resumeCh := cs.rpc.call("session.resume", cs.sessionConfig(resumeSessionID))
		select {
		case resp := <-resumeCh:
			if resp.Error != nil {
				slog.Warn("copilotSession: resume failed, creating new session", "error", resp.Error)
				return cs.createSession()
			}
			cs.sessionID.Store(resumeSessionID)
			slog.Info("copilotSession: session resumed", "sessionId", resumeSessionID)
		case <-time.After(10 * time.Second):
			return fmt.Errorf("session.resume timeout")
		case <-cs.ctx.Done():
			return cs.ctx.Err()
		}
	} else {
		return cs.createSession()
	}
	return nil
}

func (cs *copilotSession) createSession() error {
	_, createCh := cs.rpc.call("session.create", cs.sessionConfig(newCopilotSessionID()))
	select {
	case resp := <-createCh:
		if resp.Error != nil {
			return fmt.Errorf("session.create: %w", resp.Error)
		}
		var result struct {
			SessionID string `json:"sessionId"`

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Retry starting the session — transient slowness is the most common cause; a fresh handshake often resumes in time.
  2. Start a fresh session instead of resuming: clear the stored previous sessionID (e.g. run /new or delete the persisted session state) so handshake falls into createSession().
  3. Check the Copilot CLI process health: confirm the binary launches and responds (cc-connect doctor / run the CLI manually).
  4. Increase the 10s timeout in agent/copilot/session.go if your host is consistently slow to start the CLI.
  5. Inspect copilot CLI logs/stderr for a resume-time deadlock or auth prompt blocking startup.

Example fix

// before: handshake always tries resume with stale ID
resumeSessionID := cs.prevSessionID
...
// after: drop stale session state so a fresh session is created
// (user action) /new  — or in code, start the agent with an empty sessionID
opts.SessionID = ""
Defensive patterns

Strategy: retry

Validate before calling

if err := exec.Command(cliPath, "--version").Run(); err != nil {
    return fmt.Errorf("copilot CLI not runnable: %w", err)
}

Try / catch

err := agent.StartSession(ctx, opts)
if err != nil && strings.Contains(err.Error(), "session.resume timeout") {
    // drop stale session and retry fresh
    opts.SessionID = ""
    err = agent.StartSession(ctx, opts)
}

Prevention

When it happens

Trigger: newCopilotSession -> handshake -> cs.rpc.call("session.resume", ...) with a non-empty previous sessionID, and no response arrives on the create/resume channel before time.After(10*time.Second) fires (the CLI is hung, slow to start, or its stdout reader is stalled).

Common situations: Copilot CLI binary starting slowly under heavy load or cold start; the previous sessionID in the persisted state is valid but the CLI deadlocks on resume; stdout pipe backpressure because the previous readLoop died; running on a heavily throttled machine (CI container, low-memory host).

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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