chenhg5/cc-connect · error

codex app-server stdout pipe: %w

Error message

codex app-server stdout pipe: %w

What it means

This error wraps a failure from cmd.StdoutPipe() when bootstrapping the codex app-server child process. Without the stdout pipe the session cannot read JSON-RPC responses from the app-server, so startup aborts. Like the sibling stdin/stderr pipe errors, it almost always indicates OS-level resource exhaustion rather than a codex-side problem.

Source

Thrown at agent/codex/appserver_session.go:270

		args = append(args, "-c", fmt.Sprintf("openai_base_url=%q", baseURL))
	}
	cmd := exec.CommandContext(s.ctx, "codex", args...)
	cmd.Dir = s.workDir
	env := append([]string(nil), s.extraEnv...)
	if s.codexHome != "" {
		env = append(env, "CODEX_HOME="+s.codexHome)
	}
	if len(env) > 0 {
		cmd.Env = core.MergeEnv(os.Environ(), env)
	}

	stdin, err := cmd.StdinPipe()
	if err != nil {
		return fmt.Errorf("codex app-server stdin pipe: %w", err)
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return fmt.Errorf("codex app-server stdout pipe: %w", err)
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return fmt.Errorf("codex app-server stderr pipe: %w", err)
	}
	if err := cmd.Start(); err != nil {
		return fmt.Errorf("codex app-server start: %w", err)
	}

	s.procMu.Lock()
	s.cmd = cmd
	s.stdin = stdin
	s.procMu.Unlock()

	slog.Info("codex app-server session started", "transport", "stdio", "pid", cmd.Process.Pid, "work_dir", s.workDir)

	s.wg.Add(3)
	go s.readLoop(stdout)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Raise RLIMIT_NOFILE for the cc-connect process (ulimit -n or systemd LimitNOFILE).
  2. Audit for pipe/fd leaks across session lifecycle: every Start should have a matching Close that releases pipes.
  3. Restart the daemon to reclaim descriptors immediately.

Example fix

// before
stdout, err := cmd.StdoutPipe()
if err != nil {
    return fmt.Errorf("codex app-server stdout pipe: %w", err)
}
// after
// fix at the environment level instead:
// systemd: LimitNOFILE=8192 in cc-connect.service
stdout, err := cmd.StdoutPipe()
if err != nil {
    return fmt.Errorf("codex app-server stdout pipe (check fd limit): %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

var lim syscall.Rlimit
syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim)
if fdCount() > int(lim.Cur)-64 {
    return errors.New("fd limit nearly exhausted; raise RLIMIT_NOFILE before starting sessions")
}

Try / catch

if err := session.Start(ctx); err != nil {
    if errors.Is(err, syscall.EMFILE) || errors.Is(err, syscall.ENFILE) {
        slog.Error("pipe creation failed: fd exhaustion", "err", err)
        return err
    }
    return err
}

Prevention

When it happens

Trigger: Calling StartSession on the codex agent; the process-startup path calls cmd.StdoutPipe() and the OS returns an error (typically EMFILE/ENFILE from fd exhaustion).

Common situations: File-descriptor limits exhausted on a busy daemon; long-running process leaking pipes from previous sessions; hardened containers with restrictive rlimits.

Related errors


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