chenhg5/cc-connect · warning
wait outgoing: %w
Error message
wait outgoing: %w
What it means
This error wraps a failure of Engine.waitOutgoing during a restart notification send loop. Before sending the 'restart succeeded' text, the engine waits for the platform's outgoing-message queue to drain; waitOutgoing failing (timeout or platform client not accepting outgoing messages) produces 'wait outgoing: %w'. The loop retries up to 3 times with backoff (0ms, 500ms, 1500ms); if every attempt fails, the last wrapped error is returned.
Source
Thrown at core/engine.go:305
return fmt.Errorf("platform %q does not support ReconstructReplyCtx", req.Platform)
}
rctx, err := rc.ReconstructReplyCtx(req.SessionKey)
if err != nil {
return fmt.Errorf("reconstruct reply ctx: %w", err)
}
text := e.i18n.T(MsgRestartSuccess)
if CurrentVersion != "" {
text += fmt.Sprintf(" (%s)", CurrentVersion)
}
backoffs := []time.Duration{0, 500 * time.Millisecond, 1500 * time.Millisecond}
var lastErr error
for attempt, wait := range backoffs {
if wait > 0 {
time.Sleep(wait)
}
if err := e.waitOutgoing(p); err != nil {
lastErr = fmt.Errorf("wait outgoing: %w", err)
slog.Warn("restart notify: wait outgoing failed",
"platform", req.Platform, "attempt", attempt+1, "error", err)
continue
}
if err := p.Send(e.ctx, rctx, text); err != nil {
lastErr = err
slog.Warn("restart notify: send failed, will retry",
"platform", req.Platform, "session", req.SessionKey,
"attempt", attempt+1, "max_attempts", len(backoffs), "error", err)
continue
}
if attempt > 0 {
slog.Info("restart notify: send succeeded after retry",
"platform", req.Platform, "session", req.SessionKey, "attempt", attempt+1)
}
return nil
}
return lastErrView on GitHub (pinned to 4000b2338a)
Solutions
- Read the wrapped inner error to determine whether it is a timeout or a closed/broken connection; reconnect the platform adapter if needed.
- Increase the backoff window or waitOutgoing timeout if the platform is slow to drain after restart (large queued backlog).
- Ensure the platform Start() has fully completed before triggering /restart so the outgoing path is ready when the notify fires.
- Retry after the platform reconnects — this is transient in most restart scenarios.
- If the target chat is unreachable (bot removed), the send will keep failing; verify chat reachability (see reconstruct error) instead of tuning waits.
Example fix
// before: notify fails because outgoing queue not ready right after re-exec
// after: give the platform a grace period before the notify loop
func afterRestart(p core.Platform) {
time.Sleep(2 * time.Second) // let adapter re-establish connection
engine.NotifyRestart(req)
} Defensive patterns
Strategy: retry
Validate before calling
// Go: probe that the platform can accept outgoing messages before restart
if err := engine.WaitOutgoing(platform); err != nil {
log.Printf("outgoing path not ready, defer restart: %v", err)
} Try / catch
if err := engine.NotifyRestart(req); err != nil {
if strings.Contains(err.Error(), "wait outgoing") {
// already retried 3x internally; schedule a later manual re-notify
slog.Warn("outgoing queue never drained after restart", "err", err)
}
} Prevention
- Ensure platform Start() completes (connection established) before invoking /restart.
- Avoid restarting while a large outgoing backlog is pending; drain first.
- Keep the backoff window generous enough for slow platforms.
- Verify network/websocket connectivity of the platform adapter after re-exec.
When it happens
Trigger: Inside dispatchRestartNotify's retry loop, e.waitOutgoing(p) returns an error on all attempts — outgoing queue never drains after restart, platform client's send channel is closed/saturated, or the platform reports it cannot accept outbound messages yet.
Common situations: Immediately after process re-exec the platform adapter reconnects but its outgoing queue is still blocked; a flood of queued messages delays draining past the wait timeout; platform connection (websocket/long-poll) not yet re-established when the notify fires.
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
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/7cda14acc84337cb.
Report an issue: GitHub.