chenhg5/cc-connect · error

runtime config stdin pipe: %w

Error message

runtime config stdin pipe: %w

What it means

loadCodexRuntimeConfig spawns the codex app-server to query runtime configuration and failed while creating the child process's stdin pipe via cmd.StdinPipe(). The os/exec pipe factory returns an error only when the OS denies pipe creation or the process is in an invalid state, so this almost always indicates OS-level resource exhaustion or misuse of the exec.Cmd.

Source

Thrown at agent/codex/session.go:669

func codexToolSuccess(status string, exitCode *int) bool {
	s := strings.ToLower(strings.TrimSpace(status))
	if exitCode != nil {
		return *exitCode == 0
	}
	return s == "completed" || s == "success" || s == "succeeded" || s == "ok"
}

func loadCodexRuntimeConfig(ctx context.Context, workDir string, extraEnv []string) (string, string, error) {
	cmd := exec.CommandContext(ctx, "codex", "app-server")
	cmd.Dir = workDir
	prepareCmdForKill(cmd)
	if len(extraEnv) > 0 {
		cmd.Env = core.MergeEnv(os.Environ(), extraEnv)
	}

	stdin, err := cmd.StdinPipe()
	if err != nil {
		return "", "", fmt.Errorf("runtime config stdin pipe: %w", err)
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return "", "", fmt.Errorf("runtime config stdout pipe: %w", err)
	}
	var stderr bytes.Buffer
	cmd.Stderr = &stderr

	if err := cmd.Start(); err != nil {
		return "", "", fmt.Errorf("runtime config start app-server: %w", err)
	}
	defer func() {
		_ = stdin.Close()
		if cmd.Process != nil {
			_ = cmd.Process.Kill()
		}
		_ = cmd.Wait()
	}()

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check open file-descriptor usage (`ulimit -n`, `lsof -p <pid>`) and raise RLIMIT_NOFILE if it is exhausted.
  2. Look for leaked codex app-server child processes (`ps aux | grep codex`) and kill them; ensure sessions are stopped properly so pipes are released.
  3. Retry the operation once descriptors are freed — pipe creation is transient-conditional.
  4. If running in a restricted container, raise the nofile limit in the container/daemon configuration.

Example fix

// before: ulimit -n 256 (macOS default) exhausted by leaked app-server processes
// after: raise the soft limit before launching the daemon
ulimit -n 10240
Defensive patterns

Strategy: retry

Validate before calling

// check descriptor headroom before spawning probes
var lim syscall.Rlimit
syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim)
if lim.Cur < 4096 { // headroom for pipes
    lim.Cur = 65536
    syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim)
}

Try / catch

cfg, _, err := loadCodexRuntimeConfig(ctx, ...)
if err != nil && strings.Contains(err.Error(), "stdin pipe") {
    // transient: wait briefly and retry once after descriptors free
    time.Sleep(500 * time.Millisecond)
    cfg, _, err = loadCodexRuntimeConfig(ctx, ...)
}

Prevention

When it happens

Trigger: cmd.StdinPipe() returns a non-nil error inside loadCodexRuntimeConfig, immediately aborting runtime config retrieval with the wrapped error.

Common situations: File-descriptor exhaustion (too many open files / child processes leaked); running under a sandbox or container with a very low RLIMIT_NOFILE; hitting the process/thread limit.

Related errors


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