chenhg5/cc-connect · error
kimiSession: stdout pipe: %w
Error message
kimiSession: stdout pipe: %w
What it means
kimiSession.Send builds the exec.Cmd for the kimi CLI and calls cmd.StdoutPipe(); if the OS refuses to allocate the pipe, Send aborts with `kimiSession: stdout pipe: %w` wrapping the underlying error. StdoutPipe fails almost exclusively when file descriptors are exhausted or when cmd.Stdout/cmd.Stderr was already assigned (pipes and explicit writers are mutually exclusive in exec).
Source
Thrown at agent/kimi/session.go:213
}
}()
slog.Debug("kimiSession: launching",
"resume", ks.CurrentSessionID() != "",
"supports_print", ks.flagSupport.Print,
"args", core.RedactArgs(args))
cmd := exec.CommandContext(ctx, ks.cmd, args...)
cmd.WaitDelay = 1 * time.Second
cmd.Dir = ks.workDir
env := os.Environ()
if len(ks.extraEnv) > 0 {
env = core.MergeEnv(env, ks.extraEnv)
}
cmd.Env = env
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("kimiSession: stdout pipe: %w", err)
}
var stderrBuf bytes.Buffer
cmd.Stderr = &stderrBuf
if err := cmd.Start(); err != nil {
return fmt.Errorf("kimiSession: start: %w", err)
}
started = true
ks.wg.Add(1)
go func() {
defer cancel()
ks.readLoop(ctx, cmd, stdout, &stderrBuf, append(imageRefs, fileRefs...))
}()
return nil
}View on GitHub (pinned to 4000b2338a)
Solutions
- Check fd usage (`ls /proc/<pid>/fd | wc -l`); raise the limit (ulimit -n / systemd LimitNOFILE=65536) or fix the descriptor leak.
- Restart the cc-connect daemon to release leaked descriptors.
- Audit the kimi package for cmd.Stdout/cmd.Stderr assignments that run before StdoutPipe and remove duplicates.
- In containers, set the nofile rlimit explicitly in the deployment spec.
Example fix
// before (bug: Stdout set before piping)
cmd.Stdout = os.Stdout
stdout, err := cmd.StdoutPipe() // exec: Stdout already set
// after
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("kimiSession: stdout pipe: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// check fd headroom before starting more sessions
fds, _ := filepath.Glob("/proc/self/fd/*")
if len(fds) > 900 { // near default 1024 limit
return errors.New("too many open fds; refusing to start new session")
} Try / catch
if err := sess.Send(prompt, msgID, nil, nil); err != nil {
if strings.Contains(err.Error(), "stdout pipe") {
slog.Warn("pipe allocation failed, retrying after cleanup", "err", err)
runtime.GC() // release finalized handles
err = sess.Send(prompt, msgID, nil, nil)
}
return err
} Prevention
- Raise RLIMIT_NOFILE for the daemon (systemd LimitNOFILE=65536)
- Ensure cmd.Stdout/cmd.Stderr are never assigned before StdoutPipe in custom code
- Audit long-running sessions for leaked pipes/consoles
- Restart daemons periodically if they spawn thousands of processes
When it happens
Trigger: Send() called when the process hit its RLIMIT_NOFILE / fd limit; or a code path assigned cmd.Stdout (or cmd.Stderr) before StdoutPipe is invoked, producing exec's 'Stdout already set' error.
Common situations: Daemons running many concurrent agent sessions leaking pipes/fds until the limit; containers with low fd limits (ulimit -n 256); a refactoring bug that sets cmd.Stdout elsewhere in the package.
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: stdout pipe: %w
- antigravitySession: stdout pipe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/517766ee65371757.
Report an issue: GitHub.