chenhg5/cc-connect · error
did not respond within %s
Error message
did not respond within %s
What it means
Sent to notifySessionCloseFailure when Close() on an agent session exceeds closeTimeout and the close is abandoned. The session is marked unsafe-to-resume and the owning chat is alerted, because the underlying process may still be running.
Source
Thrown at core/engine.go:4613
case <-done:
if closeErr != nil {
slog.Error("agent session close reported failure, process may still be running",
"session", sessionKey, "error", closeErr)
// The old process may still hold this conversation open — the
// next turn must not resume into it.
e.markUnsafeResume(sessionKey)
e.notifySessionCloseFailure(sessionKey, platform, replyCtx, closeErr)
return
}
if elapsed := time.Since(closeStart); elapsed >= slowAgentClose {
slog.Warn("slow agent session close", "elapsed", elapsed, "session", sessionKey)
}
case <-time.After(closeTimeout):
slog.Error("agent session close timed out, abandoning",
"timeout", closeTimeout, "session", sessionKey)
e.markUnsafeResume(sessionKey)
e.notifySessionCloseFailure(sessionKey, platform, replyCtx,
fmt.Errorf("did not respond within %s", closeTimeout))
}
}
// notifySessionCloseFailure alerts the chat that owned a session when its
// underlying process could not be confirmed killed. Without this, a stuck
// process can keep running in the background — still holding the session's
// credentials — while the user believes /stop (or /new) already ended it.
func (e *Engine) notifySessionCloseFailure(sessionKey string, platform Platform, replyCtx any, cause error) {
if platform == nil || replyCtx == nil {
slog.Error("agent session close failed and no chat is available to alert",
"session", sessionKey, "cause", cause)
return
}
text := e.i18n.T(MsgSessionCloseFailed) + fmt.Sprintf(" (%v)", cause)
if err := e.waitOutgoing(platform); err != nil {
slog.Warn("notifySessionCloseFailure: wait outgoing failed", "session", sessionKey, "error", err)
}
if err := platform.Send(e.ctx, replyCtx, text); err != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Force-kill the leaked agent process manually (pkill the CLI binary)
- Investigate why the agent CLI hangs on Close (child process reaping, stdin/stdout not closing)
- Treat the session as unsafe — do not resume it; start a fresh session
- Increase closeTimeout if the agent legitimately needs longer, though leaking is the real issue
Example fix
// before closeTimeout := 10 * time.Second // too short for slow agent teardown // after closeTimeout := 130 * time.Second // or handle abandon + pkill path deliberately
Defensive patterns
Strategy: retry
Try / catch
engine.OnSessionCloseFailure(func(key string, err error) { if strings.Contains(err.Error(), "did not respond within") { pkillAgentProcess(key); markSessionUnsafe(key) } }) Prevention
- Harden agent CLIs to shut down promptly and reap children
- Monitor for abandoned processes after close timeouts
- Never resume sessions marked unsafe-resume; always start fresh
When it happens
Trigger: agentSession.Close() blocks longer than closeTimeout (the comment mentions up to 130s hangs); time.After fires before Close returns.
Common situations: Agent CLI hangs on shutdown (waiting on child processes, stuck network call); SIGKILL-ignoring process state; resource exhaustion in the agent process.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- antigravitySession: stdout pipe: %w
- antigravitySession: start: %w
- codex app-server stdin pipe: %w
- codex app-server stdout pipe: %w
- codex app-server stderr pipe: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/6e0db05236d42d44.
Report an issue: GitHub.