Skip to content

[FIX] Provider error classifier mislabels ReadError/Broken pipe as timeout instead of connection_lost #25

Description

@Da-Mikey

Problem (observed in real usage)

The provider error classifier tags ReadError: Errno 32 Broken pipe as failure_category: timeout. This is a misclassification — a broken pipe means the TCP connection was severed mid-stream (the remote end closed its socket), not that the request timed out. Different root causes need different recovery strategies.

Evidence (aggregated, anonymized)

  • Frequency: Every cron session dump across the 7-day window carries a broken-pipe error tagged as timeout. All 50+ error-capture request dumps show this.
  • Tool/area involved: agent/error_classifier.py — the function that maps raw provider exceptions to failure categories
  • Failure shape: The classifier sees ReadError exceptions and routes them to the timeout bucket. The actual error is Errno 32 Broken pipe, which means the remote server closed the connection — likely because the DeepSeek provider has a short idle timeout on streaming connections.

Impact on real tasks

The retry logic (and any future circuit-breaker) depends on the failure category. A misclassified connection_lost as timeout means:

  1. The agent may apply wrong retry budgets (timeout retry budgets may be smaller or larger than appropriate for connection drops).
  2. The system cannot distinguish "server is slow" from "server dropped the connection" — two problems that need different fixes.
  3. Any monitoring or alerting that aggregates by failure_category will conflate two semantically different failure modes.

Proposed direction

Add a specific connection_lost (or broken_pipe) failure category to agent/error_classifier.py. The classifier should:

  1. Check exception type: ReadError, ConnectionError, ConnectionResetError, ConnectionAbortedError, BrokenPipeError.
  2. Check error message for "broken pipe", "connection reset", "connection lost", "connection aborted".
  3. Return failure_category: connection_lost instead of timeout.
  4. Keep retryable: true (connection drops are retryable but may need a different backoff — faster reconnect, shorter initial wait).

This was identified as subtask 15b in the existing issue 15 (provider mid-stream connection loss) but was never filed as a separate, actionable unit.

Value

  • Impact: 0.6 — Non-blocking on its own, but blocks correct behavior of the connection retry mechanism and monitoring.
  • Effort: 0.15 — A single-file change in the classifier function. Add one more elif branch and the corresponding category constant.
  • Priority Score: 8.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedAccepted by evolution — sent to a PRbugSomething isn't workingfixTool/feature breakage blocking workintrospectionFound by session introspectionrejectedNot accepted by evolution — see closing comment

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions