chenhg5/cc-connect · error
read stdout: %w
Error message
read stdout: %w
What it means
The kimi session's readLoop scans the CLI process's stdout with bufio.Scanner; if scanning aborts with an error (not a clean EOF), it logs 'scanner error' and emits core.Event{Type: EventError, Error: fmt.Errorf("read stdout: %w", scanErr)} on the session's Events channel. This error is asynchronous — the caller receives it as an event, not as a Send() return value.
Source
Thrown at agent/kimi/session.go:296
// never sees EventError after EventResult from the same turn.
waitErr := cmd.Wait()
// Kimi writes "To resume this session: kimi -r <uuid>" to stderr (not stdout),
// so the scanner above never sees it. Extract it from the captured stderr
// buffer before emitting EventResult so the next turn can pass --resume.
for _, line := range strings.Split(stderrBuf.String(), "\n") {
if strings.HasPrefix(strings.TrimSpace(line), "To resume this session:") {
if id := extractResumeSessionID(line); id != "" {
ks.sessionID.Store(id)
slog.Debug("kimiSession: session id from stderr", "session_id", id)
}
break
}
}
if scanErr != nil {
slog.Error("kimiSession: scanner error", "error", scanErr)
evt := core.Event{Type: core.EventError, Error: fmt.Errorf("read stdout: %w", scanErr)}
select {
case ks.events <- evt:
case <-ks.ctx.Done():
return
}
}
if waitErr != nil {
stderrMsg := strings.TrimSpace(stderrBuf.String())
if stderrMsg != "" {
slog.Error("kimiSession: process failed", "error", waitErr, "stderr", stderrMsg)
evt := core.Event{Type: core.EventError, Error: fmt.Errorf("%s", stderrMsg)}
select {
case ks.events <- evt:
case <-ks.ctx.Done():
return
}
returnView on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped cause: if it is bufio.ErrTooLong, enlarge the scanner buffer in agent/kimi/session.go (scanner.Buffer).
- Check journalctl/dmesg for OOM kills of the kimi process and raise memory limits.
- Consume the session's Events() channel; on EventError 'read stdout', recreate the session and retry the turn.
- Reproduce manually: `kimi --prompt "..."` in the session workDir to see why stdout aborts.
Example fix
// before (agent/kimi/session.go readLoop) scanner := bufio.NewScanner(stdout) // after scanner := bufio.NewScanner(stdout) scanner.Buffer(make([]byte, 0, 64*1024), 10*1024*1024) // allow 10MB lines
Defensive patterns
Strategy: retry
Validate before calling
// no pre-call validation possible for async stream errors; watch events instead
go func() {
for evt := range sess.Events() {
if evt.Type == core.EventError {
slog.Warn("kimi stream error", "err", evt.Error)
}
}
}() Type guard
func isReadStdoutError(err error) bool {
return err != nil && strings.Contains(err.Error(), "read stdout:")
} Try / catch
for evt := range sess.Events() {
if evt.Type == core.EventError && isReadStdoutError(evt.Error) {
// recreate session and replay the last prompt
sess, _ = agent.StartSession(ctx, opts)
_ = sess.Send(lastPrompt, msgID, nil, nil)
}
} Prevention
- Watch for bufio.ErrTooLong in the wrapped error — big single-line CLI output needs a larger Scanner buffer
- Give containers enough memory so the CLI is not OOM-killed mid-response
- Always consume Events(); unhandled errors look like silent dead sessions
- Pin a stable kimi CLI version known not to crash on large outputs
When it happens
Trigger: The kimi process dies or its stdout pipe breaks mid-stream (crash, kill, context cancellation closing the pipe); stdout emits a single line exceeding bufio.Scanner's default 64KB token limit (bufio.ErrTooLong); an OS-level I/O error reading the pipe.
Common situations: kimi CLI crashing while printing one very large JSON line (big diffs easily exceed 64KB — hits the default Scanner limit); the CLI being OOM-killed mid-response; container shutdown terminating the process.
Related errors
- antigravitySession: stdout pipe: %w
- antigravitySession: start: %w
- read stdout: %w
- read stdout: %w
- codex app-server stdin pipe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cf458b190dd150e4.
Report an issue: GitHub.