{"record":{"id":"517766ee65371757","repo":"chenhg5/cc-connect","slug":"kimisession-stdout-pipe-w","errorCode":null,"errorMessage":"kimiSession: stdout pipe: %w","messagePattern":"kimiSession: stdout pipe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/kimi/session.go","lineNumber":213,"sourceCode":"\t\t}\n\t}()\n\n\tslog.Debug(\"kimiSession: launching\",\n\t\t\"resume\", ks.CurrentSessionID() != \"\",\n\t\t\"supports_print\", ks.flagSupport.Print,\n\t\t\"args\", core.RedactArgs(args))\n\tcmd := exec.CommandContext(ctx, ks.cmd, args...)\n\tcmd.WaitDelay = 1 * time.Second\n\tcmd.Dir = ks.workDir\n\tenv := os.Environ()\n\tif len(ks.extraEnv) > 0 {\n\t\tenv = core.MergeEnv(env, ks.extraEnv)\n\t}\n\tcmd.Env = env\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kimiSession: stdout pipe: %w\", err)\n\t}\n\n\tvar stderrBuf bytes.Buffer\n\tcmd.Stderr = &stderrBuf\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"kimiSession: start: %w\", err)\n\t}\n\n\tstarted = true\n\tks.wg.Add(1)\n\tgo func() {\n\t\tdefer cancel()\n\t\tks.readLoop(ctx, cmd, stdout, &stderrBuf, append(imageRefs, fileRefs...))\n\t}()\n\n\treturn nil\n}","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/kimi/session.go#L195-L231","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (bug: Stdout set before piping)\ncmd.Stdout = os.Stdout\nstdout, err := cmd.StdoutPipe() // exec: Stdout already set\n\n// after\nstdout, err := cmd.StdoutPipe()\nif err != nil {\n    return fmt.Errorf(\"kimiSession: stdout pipe: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// check fd headroom before starting more sessions\nfds, _ := filepath.Glob(\"/proc/self/fd/*\")\nif len(fds) > 900 { // near default 1024 limit\n    return errors.New(\"too many open fds; refusing to start new session\")\n}","typeGuard":null,"tryCatchPattern":"if err := sess.Send(prompt, msgID, nil, nil); err != nil {\n    if strings.Contains(err.Error(), \"stdout pipe\") {\n        slog.Warn(\"pipe allocation failed, retrying after cleanup\", \"err\", err)\n        runtime.GC() // release finalized handles\n        err = sess.Send(prompt, msgID, nil, nil)\n    }\n    return err\n}","preventionTips":["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"],"tags":["go","process","file-descriptors"],"backgroundTag":"file-open-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}