Skip to content
This repository was archived by the owner on Jul 29, 2026. It is now read-only.
This repository was archived by the owner on Jul 29, 2026. It is now read-only.

Poor network-failure handling: ConnectTimeoutError surfaces as cryptic NoOutputGeneratedError #96

Description

@minpeter

Summary

When the network is down or FriendliAI's API is unreachable, the agent fails with a confusing NoOutputGeneratedError that masks the actual ConnectTimeoutError. The error surface is misleading and the recovery path isn't friendly to users.

What happens

  1. User sends a message during network outage (or FriendliAI is down)
  2. @friendliai/ai-provider throws ConnectTimeoutError (10s timeout) via undici
  3. Vercel AI SDK's retry-with-exponential-backoff retries 3x, all fail
  4. SDK's internal stream finishes with recordedSteps.length === 0
  5. flush() at stream-text.ts:1077 rejects all 4 DelayedPromises with NoOutputGeneratedErrornot the original network error

Example trace:

```
APICallError [AI_APICallError]: Cannot connect to API: Connect Timeout Error
(attempted address: api.friendli.ai:443, timeout: 10000ms)
at handleFetchError (@ai-sdk/provider-utils/.../handle-fetch-error.ts:51:14)
at postToApi (@ai-sdk/provider-utils/.../post-to-api.ts:164:11)
at FriendliAIChatLanguageModel.doStream (@friendliai/ai-provider/.../friendli-chat-language-model.ts:447:50)
at wrapStream (packages/cea/src/middleware/trim-leading-newlines.ts:38:33)
at streamStep (ai/.../stream-text.ts:1622:17)
cause: ConnectTimeoutError { code: 'UND_ERR_CONNECT_TIMEOUT' }

NoOutputGeneratedError [AI_NoOutputGeneratedError]: No output generated. Check the stream for errors.
at Object.flush (ai/.../stream-text.ts:1077:17)
```

Why this is bad UX

  • User sees "No output generated" — completely unactionable
  • The actual root cause ("I can't reach the internet") is buried behind it
  • No retry / backoff / user-friendly message at the TUI/headless layer
  • Previous unhandled-rejection crash is fixed (#TBD), but the error rendered to the user is still unhelpful

Expected behavior

When a network / connection error occurs:

  1. Detect `ConnectTimeoutError` / `AI_APICallError` (with `isRetryable: true`) in the stream error path
  2. Report a clear message to the user: "Cannot connect to `api.friendli.ai` (timeout 10s). Check your network connection."
  3. Optional: offer to retry with a manual trigger (`r` key) or auto-retry with exponential backoff at the agent-loop level (separate from SDK's internal retries)
  4. Do NOT surface `NoOutputGeneratedError` to the user when the real cause is a network failure

Where to handle

Candidates:

  • `packages/tui/src/agent-tui.ts` — `handleStreamTurnError` / `retryStreamTurnOnNoOutput`: detect if the wrapped error has `cause?.name === 'ConnectTimeoutError'` or `cause?.code === 'UND_ERR_CONNECT_TIMEOUT'`, and render a user-friendly network-error message instead of the generic retry path
  • `packages/headless/src/runner.ts` — similar handling for JSONL event emission: emit a specific `network_error` event type
  • `packages/harness/src/loop.ts` — decide whether to expose a `networkUnreachable` finish reason

Repro

  1. Disable network (`sudo ifconfig en0 down` or similar)
  2. Run `pnpm dev` in `packages/cea`
  3. Send any message
  4. Wait 10s → see `ConnectTimeoutError` followed by `NoOutputGeneratedError`

Related

  • The unhandled rejection path for `NoOutputGeneratedError` is fixed in the current work tree (patch to `packages/harness/src/agent.ts` silencing stream result DelayedPromises)
  • This issue tracks the separate concern of user-facing error messages for network failures

Environment

  • OS: macOS (darwin)
  • Node: 22.x
  • `ai`: 6.0.116
  • `@friendliai/ai-provider`: 1.1.7
  • `@ai-sdk/provider-utils`: 4.0.15

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions