chenhg5/cc-connect · info

session cancelled

Error message

session cancelled

What it means

Notification reason attached when a session cancellation drops pending (queued) messages: on /cancel or equivalent, any pending permission request is resolved and either the queued messages get a "session cancelled" notification via notifyDroppedQueuedMessages, or the queue is silently cleared. It tells the user why their queued messages never ran.

Source

Thrown at core/engine.go:10367

	agentSession := state.agentSession
	closePlatform := state.platform
	closeReplyCtx := state.replyCtx
	state.mu.Unlock()

	// If the agent session supports graceful turn cancellation (e.g. ACP),
	// send a cancel notification and keep the session alive for the next
	// user message, rather than killing the process and destroying state.
	if canceller, ok := agentSession.(AgentSessionCanceller); ok && agentSession != nil {
		// Keep the state in the map so the next message reuses this session.
		// Don't markStopped — the session is still usable.
		// Don't delete from interactiveStates — keep it alive.
		e.interactiveMu.Unlock()

		if pending != nil {
			pending.resolve()
		}
		if notifyQueued {
			e.notifyDroppedQueuedMessages(state, fmt.Errorf("session cancelled"))
		} else {
			state.mu.Lock()
			state.pendingMessages = nil
			state.mu.Unlock()
		}

		// Mark eventsNeedResync so the next turn drains stale events from
		// the cancelled turn before processing fresh input.
		state.mu.Lock()
		state.eventsNeedResync = true
		state.mu.Unlock()

		cancelErr := canceller.CancelTurn()
		if cancelErr != nil {
			slog.Warn("agent session CancelTurn failed, falling back to Close",
				"session_key", sessionKey, "error", cancelErr)
			// Fall through to normal cleanup below.
			goto normalCleanup

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Expected behavior, not a fault: re-send the messages after starting a new session
  2. If unintentional, avoid /cancel while messages are queued; check the session has no pendingMessages first
  3. Drain/complete the current task before issuing /cancel if the queued work is still wanted
Defensive patterns

Strategy: try-catch

Try / catch

This is an intentional notification, not an exception: handle the dropped-message notification by surfacing it to the user and offering to re-send queued content after a new session starts.

Prevention

When it happens

Trigger: User issues /cancel (or the cancel API) while messages sit in state.pendingMessages; notifyQueued=true routes the error string to the dropped-message notifier instead of silently discarding the queue.

Common situations: User cancels a long-running agent task while follow-up messages are still queued; automated scripts fire messages then cancel; user changes mind mid-task.

Related errors


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