{"record":{"id":"0afacd4aa74b1165","repo":"chenhg5/cc-connect","slug":"read-stdout-w","errorCode":null,"errorMessage":"read stdout: %w","messagePattern":"read stdout: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/antigravity/session.go","lineNumber":303,"sourceCode":"\n\treader := bufio.NewReader(stdout)\n\tbuf := make([]byte, 1024)\n\n\tfor {\n\t\tn, err := reader.Read(buf)\n\t\tif n > 0 {\n\t\t\ttext := string(buf[:n])\n\t\t\tselect {\n\t\t\tcase as.events <- core.Event{Type: core.EventText, Content: text}:\n\t\t\tcase <-as.ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\tif err != io.EOF && !strings.Contains(err.Error(), \"file already closed\") {\n\t\t\t\tslog.Error(\"antigravitySession: read error\", \"error\", err)\n\t\t\t\tselect {\n\t\t\t\tcase as.events <- core.Event{Type: core.EventError, Error: fmt.Errorf(\"read stdout: %w\", err)}:\n\t\t\t\tcase <-as.ctx.Done():\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (as *antigravitySession) detectNewSessionID(preEntries map[string]bool, sendStartedAt time.Time) string {\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tslug := antigravityProjectSlug(as.workDir)\n\tchatsDir := filepath.Join(homeDir, \".gemini\", \"tmp\", slug, \"chats\")\n\n\tentries, err := os.ReadDir(chatsDir)\n\tif err != nil {","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/antigravity/session.go#L285-L321","documentation":"The goroutine reading the agy process's stdout hit a read error other than EOF or the benign 'file already closed' (which happens on normal cancellation). The raw OS read error is wrapped as 'read stdout: %w' and delivered as a core.EventError. It indicates the stdout pipe broke unexpectedly rather than the process finishing.","triggerScenarios":"reader.Read on the agy stdout pipe returns a non-EOF error, e.g. the pipe descriptor is invalid, the process was killed with SIGKILL leaving a broken pipe, or an fd was closed concurrently outside the normal ctx cancellation path.","commonSituations":"agy process crashed hard or was OOM-killed; system resource exhaustion (fd limits); external kill of the child process; rare kernel-level pipe errors.","solutions":["Check whether the agy process crashed (dmesg / OOM killer logs) and fix the underlying crash","Verify ulimit -n and system resources are not exhausted","Retry the turn; transient pipe errors usually disappear on rerun","If you cancel sessions, confirm cancellation goes through ctx (which closes stdout gracefully and is filtered) rather than killing the process directly"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight: ensure resources OK\nif n := len(processList(\"agy\")); n > 0 { /* prior agy still running? kill stale ones */ }","typeGuard":null,"tryCatchPattern":"if evt.Type == core.EventError && strings.HasPrefix(evt.Error.Error(), \"read stdout:\") {\n    slog.Warn(\"transient stdout read failure; retrying turn\", \"err\", evt.Error)\n    // re-dispatch the turn\n}","preventionTips":["Avoid SIGKILLing agy; cancel via session Stop/ctx so stdout close is filtered","Raise fd limits on hosts running many sessions","Monitor for OOM kills of the agy process"],"tags":["process","io","stdout","pipe"],"backgroundTag":"broken-pipe","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"}