chenhg5/cc-connect · warning

agent process exited

Error message

agent process exited

What it means

Emitted when the read side of an agent session's event pipe closes unexpectedly, i.e. the agent CLI process died while the engine was streaming its events. The engine marks the session as needing event resync, notifies the user that queued messages were dropped, and tears down interactive state (pending permissions, typing indicators). This is a warning-level lifecycle signal, not a bug in cc-connect itself.

Source

Thrown at core/engine.go:6305

				e.send(p, replyCtx, userMsg)
			}
			// Only drop queued messages if the agent session is dead.
			// Some agents (e.g. Codex) emit EventError for per-turn failures
			// while keeping the session alive for subsequent turns.
			if state.agentSession == nil || !state.agentSession.Alive() {
				e.notifyDroppedQueuedMessages(state, event.Error)
			}
			return
		}
	}

channelClosed:
	// Channel closed - process exited unexpectedly
	slog.Warn("agent process exited", "session_key", sessionKey)
	state.mu.Lock()
	state.eventsNeedResync = true
	state.mu.Unlock()
	e.notifyDroppedQueuedMessages(state, fmt.Errorf("agent process exited"))
	e.cleanupInteractiveState(sessionKey, state)

	if len(textParts) > 0 {
		state.mu.Lock()
		p := state.platform
		state.mu.Unlock()

		fullResponse := strings.Join(textParts, "")
		session.AddHistory("assistant", fullResponse)
		// Persist immediately — this path runs on abnormal channel close,
		// so deferring the save until the next foreground turn risks losing
		// the partial assistant response if the process exits next.
		sessions.Save()

		// Respect NO_REPLY even on abnormal exit so silent turns stay silent.
		if isSilentReply(fullResponse) {
			sp.discard()
			slog.Info("silent reply suppressed (channel closed)", "session", session.ID)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the agent process logs/stderr just before exit (engine logs session_key) to find the agent's own crash output
  2. Re-send the message to start a fresh session; queued messages are dropped by design
  3. Verify the agent CLI is installed and runs standalone (e.g. `claude --version`); upgrade or reinstall it
  4. Check container/host memory limits (dmesg for oom-kill) and raise them if the agent is being killed
  5. Run `cc-connect doctor` to validate the agent binary configuration

Example fix

// before: agent binary pinned to a broken/old version, crashing on start
command = "claude"

// after: pin a known-good version and let doctor verify it
command = "claude"
// then: cc-connect doctor  -> confirms CLI binary is present and healthy
Defensive patterns

Strategy: try-catch

Validate before calling

if err := exec.Command(agentBin, "--version").Run(); err != nil { log.Fatalf("agent binary %q not runnable: %v", agentBin, err) }

Try / catch

Treat the warning as a session-death signal: watch session events and on `agent process exited`, restart the session via StartSession and re-dispatch pending work. In-process code should select on session Events() and handle a closed channel rather than blocking forever.

Prevention

When it happens

Trigger: The `events` channel in the session's event loop hits the `channelClosed` branch (agent stdout/stderr closed and the process returned). Caused by the agent binary exiting: crash, panic, OOM kill, SIGKILL/SIGTERM from outside, or the user quitting inside the agent.

Common situations: Agent CLI binary corrupted or updated mid-session; OOM killer reaping a large claude/codex process; container memory limits; agent crashing on a malformed prompt; system shutdown killing the child process.

Related errors


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