chenhg5/cc-connect · error

acp: no agent session id

Error message

acp: no agent session id

What it means

A sentinel guard in acpSession.Send: before shipping the prompt over the ACP session/new or session/prompt path, the session checks its stored agent-side session ID and finds it empty. It fires when Send is called before the initialize/session/new handshake completed (or the ID was never captured), so there is no ACP session to address.

Source

Thrown at agent/acp/session.go:606

}

func (s *acpSession) Send(prompt string, messageID string, images []core.ImageAttachment, files []core.FileAttachment) error {
	if !s.alive.Load() {
		return fmt.Errorf("acp: session closed")
	}

	s.sendMu.Lock()
	defer s.sendMu.Unlock()

	filePaths := core.SaveFilesToDisk(s.workDir, messageID, files)
	prompt = core.AppendFileRefs(prompt, filePaths)
	if len(images) > 0 {
		prompt = s.appendImageRefs(prompt, images)
	}

	sid := s.currentACPSessionID()
	if sid == "" {
		return fmt.Errorf("acp: no agent session id")
	}

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

	slog.Debug("acp: sending session/prompt", "session_id", sid, "prompt_len", len(prompt))
	res, err := s.tr.call(s.ctx, "session/prompt", params)
	if err != nil {
		s.emit(core.Event{Type: core.EventError, Error: err})
		return fmt.Errorf("acp: session/prompt: %w", err)
	}
	slog.Debug("acp: session/prompt response", "session_id", sid, "response_len", len(res), "response", string(res))

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Ensure the session went through the full handshake (initialize → session/new or session/load) before calling Send.
  2. Recreate the session via StartSession/newACPSession so session/new runs and caches an id.
  3. If using a custom transport/embedding, verify setACPSessionID is called with the id from session/new.
  4. Check agent output: an empty sessionId from session/new points back to error [45]; fix the agent first.

Example fix

// before: sending right after a failed handshake
sess, _ := agent.StartSession(ctx, id, nil) // handshake failed
sess.Send(prompt, mid, nil, nil)            // "acp: no agent session id"
// after: check the error before sending
sess, err := agent.StartSession(ctx, id, nil)
if err != nil {
    return err
}
sess.Send(prompt, mid, nil, nil)
Defensive patterns

Strategy: validation

Validate before calling

// before Send: ensure a session id exists
if err := sess.Send("ping", probeMsgID, nil, nil); err != nil && strings.Contains(err.Error(), "no agent session id") {
    return fmt.Errorf("session not initialized; rerun StartSession")
}

Try / catch

if err := sess.Send(prompt, mid, nil, nil); err != nil {
    if strings.Contains(err.Error(), "acp: no agent session id") {
        ns, rerr := agent.StartSession(ctx, id, nil)
        if rerr != nil { return rerr }
        return ns.Send(prompt, mid, nil, nil)
    }
    return err
}

Prevention

When it happens

Trigger: currentACPSessionID() returns "" at Send time — e.g. a session object created without a completed handshake, a session/new response with empty sessionId that was somehow tolerated, or internal state corruption after close/restart.

Common situations: Custom embedding that constructs acpSession without running handshake; an agent that never returned a valid session id but the session was kept alive; concurrency bug clearing acpSessID.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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