chenhg5/cc-connect · error

tmux: create session %q: %w

Error message

tmux: create session %q: %w

What it means

When the tmux session is missing and auto_create is enabled, StartSession calls createTmuxSession and wraps any underlying failure with 'tmux: create session %q: %w'. This is the intermediate wrap around the raw tmux exec error (errorIndex 350), preserving both the session name and tmux's own output.

Source

Thrown at agent/tmux/tmux.go:181

	//     isolation; each gets its own init_command/agent instance).
	//   - else, when workDir is a real path: a window named after the directory
	//     so each workspace gets its own instance.
	//   - else: the legacy session:pane target.
	// windowForSession may allocate a fresh window name when sessionID is empty;
	// the returned ID is persisted by the engine so resumes reuse the same window.
	windowName, effectiveSessionID := a.windowForSession(sessionName, pane, workDir, sessionID)
	sessionID = effectiveSessionID
	target := sessionName + ":" + windowName

	sessionExists := tmuxSessionExists(sessionName)
	windowExists := sessionExists && tmuxWindowExists(target)

	if !sessionExists {
		if !autoCreate {
			return nil, fmt.Errorf("tmux: session %q does not exist and auto_create is disabled", sessionName)
		}
		if err := createTmuxSession(sessionName, windowName, workDir, shell); err != nil {
			return nil, fmt.Errorf("tmux: create session %q: %w", sessionName, err)
		}
		slog.Info("tmux: created session", "session", sessionName, "window", windowName, "work_dir", workDir)
	} else if !windowExists && windowName != pane {
		// Session exists but this workspace window does not yet — create it.
		if err := createTmuxWindow(sessionName, windowName, workDir); err != nil {
			return nil, fmt.Errorf("tmux: create window %q in session %q: %w", windowName, sessionName, err)
		}
		slog.Info("tmux: created window", "session", sessionName, "window", windowName, "work_dir", workDir)
	}

	newPane := !sessionExists || (!windowExists && windowName != pane)
	if newPane {
		// Always cd to the workspace directory so the shell (and any init_command)
		// starts in the right place, regardless of tmux's -c flag behaviour.
		if workDir != "" && workDir != "." {
			if err := sendKeys(target, "cd "+shellQuote(workDir)); err != nil {
				slog.Warn("tmux: cd failed", "work_dir", workDir, "err", err)
			}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the wrapped inner error for tmux's message
  2. Create the work_dir or fix the work_dir value in config
  3. Fix or remove the shell option if it names a missing binary
  4. Create the session manually with tmux new-session -d -s <name> and disable auto_create

Example fix

// before
[agents.options]
session = "cc"
auto_create = true
work_dir = "/srv/app" # does not exist

// after
mkdir -p /srv/app
# or point work_dir at an existing path
work_dir = "/home/user/app"
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(workDir); err != nil { return fmt.Errorf("auto_create work_dir missing: %w", err) }
if shell != "" { if _, err := exec.LookPath(shell); err != nil { return err } }

Try / catch

if _, err := agent.StartSession(ctx, opts); err != nil {
    var inner error
    if errors.Unwrap(errors.Unwrap(err)) != nil { inner = errors.Unwrap(errors.Unwrap(err)) }
    slog.Error("tmux auto-create failed", "session", sessionName, "cause", inner)
    return err
}

Prevention

When it happens

Trigger: auto_create = true, session does not exist, and `tmux new-session` fails: nonexistent work_dir (-c), invalid shell, or tmux server error creating the session.

Common situations: work_dir pointing to a directory that does not exist yet (e.g. project not cloned); shell option naming an uninstalled binary; concurrent auto-create of the same session name by two agents.

Related errors


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