chenhg5/cc-connect · error
copilot probe: stdout pipe: %w
Error message
copilot probe: stdout pipe: %w
What it means
This error wraps the failure to create an stdout pipe on the `copilot` CLI process that the probe session spawns to list/delete sessions via LSP-style JSON-RPC. It is thrown by newProbeSession when cmd.StdoutPipe() returns an error, before the process is started. It almost always indicates an OS-level resource problem (too many open files, exhausted pipes) rather than a copilot configuration issue.
Source
Thrown at agent/copilot/copilot.go:223
// newProbeSession spawns a copilot --headless --stdio probe process, starts a
// read loop, and returns a probeSession. Caller must call close() when done.
func newProbeSession(ctx context.Context, snapshot probeSnapshot) (*probeSession, error) {
probeCtx, cancel := context.WithCancel(ctx)
cmd := exec.CommandContext(probeCtx, snapshot.cmd, "--headless", "--stdio", "--no-auto-update")
cmd.Dir = snapshot.workDir
cmd.Env = snapshot.env
stdin, err := cmd.StdinPipe()
if err != nil {
cancel()
return nil, fmt.Errorf("copilot probe: stdin pipe: %w", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
cancel()
return nil, fmt.Errorf("copilot probe: stdout pipe: %w", err)
}
cmd.Stderr = io.Discard
if err := cmd.Start(); err != nil {
cancel()
return nil, fmt.Errorf("copilot probe: start: %w", err)
}
rpc := newRPCClient(stdin)
reader := newLSPReader(stdout)
done := make(chan struct{})
go func() {
defer func() {
_ = stdin.Close()
_ = cmd.Wait()
close(done)
}()View on GitHub (pinned to 4000b2338a)
Solutions
- Check for leaked copilot processes / probe sessions not being closed (LookPath/spawn leaks) and fix the leak
- Raise the file-descriptor limit (ulimit -n) for the cc-connect daemon process
- In containers, raise RLIMIT_NOFILE (e.g. docker --ulimit nofile=65536:65536)
- Retry the ListSessions/DeleteSession call once resources are freed
Example fix
// before
cmd := exec.CommandContext(ctx, bin, args...)
stdout, err := cmd.StdoutPipe() // fails under fd exhaustion
// after
// ensure previous probe cmd.Wait() is always called via defer so pipes close
func (a *Agent) newProbeSession(ctx context.Context) (*probeSession, error) {
ctx, cancel := context.WithTimeout(ctx, probeTimeout)
defer func() { ... }()
cmd := exec.CommandContext(ctx, bin, args...)
stdout, err := cmd.StdoutPipe()
if err != nil { cancel(); return nil, fmt.Errorf("copilot probe: stdout pipe: %w", err) }
...
} Defensive patterns
Strategy: retry
Validate before calling
// before calling ListSessions/DeleteSession
func fdsAvailable(minFree uint64) bool {
entries, err := os.ReadDir("/proc/self/fd")
if err != nil { return true }
var rlim syscall.Rlimit
syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim)
return uint64(len(entries))+minFree < rlim.Cur
} Try / catch
err := a.ListSessions(ctx)
if err != nil && strings.Contains(err.Error(), "stdout pipe") {
slog.Warn("fd exhaustion suspected; retrying after GC/close", "err", err)
runtime.GC()
err = a.ListSessions(ctx)
} Prevention
- Always Wait() probe commands so pipes/fds are released
- Monitor open fd counts for the daemon in production
- Set generous RLIMIT_NOFILE for the cc-connect service unit (LimitNOFILE=65536)
When it happens
Trigger: Calling ListSessions or DeleteSession when the os/exec StdoutPipe call fails, typically because the process has exhausted its file-descriptor limit (EMFILE) or the pipe syscall fails.
Common situations: Long-running cc-connect daemons leaking copilot probe processes and hitting the ulimit -n / RLIMIT_NOFILE ceiling; containers with low fd limits; running under a heavily loaded system where pipe allocation fails.
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
- codex app-server stdin pipe: %w
- codex app-server stdout pipe: %w
- codex app-server stderr pipe: %w
- copilot probe: stdin pipe: %w
- copilot probe: start: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/3343ee308a55a093.
Report an issue: GitHub.