chenhg5/cc-connect · error
claudeSession: stdin pipe: %w
Error message
claudeSession: stdin pipe: %w
What it means
newClaudeSession wraps the error returned by cmd.StdinPipe() when the os/exec package cannot create the stdin pipe for the spawned `claude` process. This almost always means an OS-level resource problem (file descriptor exhaustion) or calling StdinPipe after Start, which this code never does. The session is aborted (context cancelled) and never returned.
Source
Thrown at agent/claudecode/session.go:427
var providerEnvSnapshot []string
for _, e := range env {
for _, prefix := range []string{"ANTHROPIC_", "CLAUDE_", "AWS_", "NO_PROXY", "DISABLE_"} {
if strings.HasPrefix(e, prefix) {
providerEnvSnapshot = append(providerEnvSnapshot, e)
break
}
}
}
slog.Debug("claudeSession: spawn details",
"bin", cliBin,
"allArgs", core.RedactArgs(allArgs),
"model", model,
"providerEnv", core.RedactEnv(providerEnvSnapshot))
stdin, err := cmd.StdinPipe()
if err != nil {
cancel()
return nil, fmt.Errorf("claudeSession: stdin pipe: %w", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
cancel()
return nil, fmt.Errorf("claudeSession: stdout pipe: %w", err)
}
var stderrBuf bytes.Buffer
cmd.Stderr = &stderrBuf
// 🔴 /stop「杀不死」的根因修复(2026-07-29)。
//
// 症状:taskkill /T /F 报成功,Close() 却在 10 秒后返回
// "process tree (pid N) still alive 10s after SIGKILL reported success",
// engine 于是认定 teardown 失败 —— 用户按了 /stop,却像在跟另一个 session 说话。
//
// 机制:上面这行把 stderr 接到 *bytes.Buffer(不是 *os.File),os/exec 因此会View on GitHub (pinned to 4000b2338a)
Solutions
- Check and raise the file descriptor limit (ulimit -n / systemd LimitNOFILE) on the host running cc-connect
- Audit for fd leaks: lsof -p <cc-connect-pid> | wc -l and compare to ulimit -n; restart the daemon to reclaim fds
- Reduce concurrent sessions (each session consumes multiple pipes) or enable session recycling
- Retry session creation once fds are freed; the error is wrapped so inspect %w for the underlying os.SyscallError
Example fix
// before // daemon started with default LimitNOFILE=1024, hundreds of sessions leak fds // after # systemd unit [Service] LimitNOFILE=65536
Defensive patterns
Strategy: fallback
Validate before calling
import "syscall"
func fdsAvailable(min int) bool {
var lim syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
return false
}
return lim.Cur > uint64(min)
} Try / catch
sess, err := agent.StartSession(ctx, prompt)
if err != nil && strings.Contains(err.Error(), "stdin pipe") {
// fd exhaustion: wait/backoff, then retry once
time.Sleep(2 * time.Second)
sess, err = agent.StartSession(ctx, prompt)
}
if err != nil { return err } Prevention
- Raise LimitNOFILE/ulimit -n for the daemon (systemd unit or shell profile)
- Monitor open fd count of the cc-connect process and alert near the limit
- Bound concurrent agent sessions in configuration
- Restart the daemon on a schedule if it handles very high session churn
When it happens
Trigger: newClaudeSession calls cmd.StdinPipe() and it returns an error — practically only when the process has exhausted file descriptors (ulimit -n reached, fd leak elsewhere) or the OS denies pipe allocation.
Common situations: Long-running cc-connect daemons that leaked sockets/files until hitting the nofile ulimit; containers with very low fd limits; system-wide pipe/memory pressure.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- claudeSession: stdout pipe: %w
- claudeSession: start: %w
- stdin pipe: %w
- stdout pipe: %w
- acp: probe stdin pipe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/da9aab7375f3c59a.
Report an issue: GitHub.