chenhg5/cc-connect · error

session is closed

Error message

session is closed

What it means

Sentinel guard returned when Send is called on a codexSession whose Stop() has already run, meaning the underlying codex subprocess is gone and the session can no longer accept prompts.

Source

Thrown at agent/codex/session.go:127

	cs.alive.Store(true)

	if resumeID != "" && resumeID != core.ContinueSession {
		cs.threadID.Store(resumeID)
	}

	return cs, nil
}

// Send launches a codex subprocess.
// If a threadID exists (from a prior turn or resume), uses `codex exec resume <id> <prompt>`.
// Otherwise uses `codex exec <prompt>` to start a new conversation.
func (cs *codexSession) Send(prompt string, messageID string, images []core.ImageAttachment, files []core.FileAttachment) error {
	if len(files) > 0 {
		filePaths := core.SaveFilesToDisk(cs.workDir, messageID, files)
		prompt = core.AppendFileRefs(prompt, filePaths)
	}
	if !cs.alive.Load() {
		return fmt.Errorf("session is closed")
	}

	prompt, imagePaths, err := cs.stageImages(prompt, images)
	if err != nil {
		return err
	}

	isResume := cs.CurrentSessionID() != ""
	if !isResume {
		prompt = prependCodexPromptPreamble(prompt, cs.promptPreamble)
	}
	args := cs.buildExecArgs(prompt, imagePaths)
	if len(cs.cliExtraArgs) > 0 {
		args = append(append([]string{}, cs.cliExtraArgs...), args...)
	}

	bin := cs.cmd
	if bin == "" {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Start a new session via the agent instead of reusing the closed one
  2. Check the session's alive flag before calling Send
  3. Track session lifecycle in the caller so closed sessions are evicted from any active map
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at agent/codex/session.go:127 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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