chenhg5/cc-connect · error
acp: session/new: empty sessionId
Error message
acp: session/new: empty sessionId
What it means
Raised when the `session/new` call succeeded and parsed, but the returned sessionId field is empty. An ACP session without an id is unusable (session/prompt needs it), so the handshake is treated as failed.
Source
Thrown at agent/acp/session.go:246
}
newParams := map[string]any{
"cwd": s.workDir,
"mcpServers": []any{},
}
newRes, err := s.tr.call(s.ctx, "session/new", newParams)
if err != nil {
return fmt.Errorf("acp: session/new: %w", err)
}
var sn struct {
SessionID string `json:"sessionId"`
Modes *acpModesBlock `json:"modes"`
}
if err := json.Unmarshal(newRes, &sn); err != nil {
return fmt.Errorf("acp: parse session/new: %w", err)
}
if sn.SessionID == "" {
return fmt.Errorf("acp: session/new: empty sessionId")
}
s.setACPSessionID(sn.SessionID)
s.absorbModes(sn.Modes)
return nil
}
// absorbModes copies a modes block into the session's cache and fans
// it out to the parent agent callbacks (if any). Both the session and
// the agent need the information: the session uses it to validate
// SetLiveMode inputs; the agent uses it to render `/mode` menus in IM.
func (s *acpSession) absorbModes(block *acpModesBlock) {
if block == nil || len(block.AvailableModes) == 0 {
return
}
s.modesMu.Lock()
s.availableModes = append(s.availableModes[:0], block.AvailableModes...)
if block.CurrentModeID != "" {
s.currentMode = block.CurrentModeIDView on GitHub (pinned to 4000b2338a)
Solutions
- Upgrade the agent to a version with a conforming session/new implementation.
- Check agent logs/stderr for an internal error that made it return an empty id.
- Test the agent directly with an ACP client (e.g. Zed) to confirm it returns a real sessionId.
- If a wrapper/shim produces the response, fix it to propagate the agent's actual session id.
Example fix
// non-conforming agent response
// {"sessionId": ""}
// after: agent returns
// {"sessionId": "sess_01H...", "modes": {"currentModeId": "code"}} Defensive patterns
Strategy: validation
Validate before calling
var probe struct{ SessionID string `json:"sessionId"` }
if err := json.Unmarshal(newRes, &probe); err == nil && probe.SessionID == "" {
return fmt.Errorf("agent returned empty sessionId")
} Try / catch
sess, err := agent.StartSession(ctx, id, nil)
if err != nil && strings.Contains(err.Error(), "empty sessionId") {
slog.Error("agent violates ACP session/new contract — upgrade agent", "err", err)
return err
} Prevention
- Test agents against the ACP spec (or Zed) before wiring them into cc-connect.
- Upgrade agents with known session/new bugs.
- Verify with a raw JSON-RPC probe that session/new yields a non-empty sessionId.
When it happens
Trigger: The agent's session/new result contains no `sessionId` key or an empty string value — typically a non-conforming agent or a server that reports success while failing to actually create the session.
Common situations: Agent bug or incomplete ACP implementation returning an empty id; a shim returning {"sessionId": ""} on internal error; version mismatch where the agent creates sessions lazily and does not return ids.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- acp: session/new: %w
- acp: initialize: %w
- acp: parse initialize result: %w
- acp: authenticate (%s): %w
- acp: parse session/new: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/72450bea05ce76ee.
Report an issue: GitHub.