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
- Raise RLIMIT_NOFILE for the cc-connect process (ulimit -n or systemd LimitNOFILE).
- Audit for pipe/fd leaks across session lifecycle: every Start should have a matching Close that releases pipes.
- 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
- Ensure every Start has a matching Close that releases stdin/stdout/stderr pipes.
- Raise LimitNOFILE for the daemon service.
- Watch /proc/<pid>/fd count for leaks.
- Use a race detector on session lifecycle tests.
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
- codex app-server stdin pipe: %w
- codex app-server stderr pipe: %w
- copilot probe: stdout pipe: %w
- geminiSession: stdout pipe: %w
- kimiSession: stdout pipe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/23ba213674cc8cdd.
Report an issue: GitHub.