stablyai/orca · error

request timed out after ${timeoutMs / 1000} seconds

Error message

request timed out after ${timeoutMs / 1000} seconds

What it means

Thrown on the happy path of `postFeedback` after `readResponse` completes: if `controller.signal.aborted` is true, the AbortController deadline fired even though the response parser finished. The code normalizes the deadline as an explicit timeout error so a parser tolerating a half-aborted body cannot be mistaken for a confirmed delivery. Default deadline is `FEEDBACK_REQUEST_TIMEOUT_MS = 10_000` ms (or 60s for attachments).

Source

Thrown at src/main/ipc/feedback.ts:128

  readResponse?: (response: Response) => Promise<void>
): Promise<Response> {
  const controller = new AbortController()
  // Why: a silent endpoint must not leave feedback IPC pending forever.
  const timeout = setTimeout(() => controller.abort(), timeoutMs)
  try {
    const init: RequestInit = {
      method: 'POST',
      ...feedbackRequestBodyInit(body),
      signal: controller.signal
    }
    const response = await net.fetch(url, init)
    if (readResponse) {
      await readResponse(response)
    }
    // Why: a response parser may tolerate malformed legacy bodies, but it must
    // not turn the deadline's aborted body into a confirmed delivery.
    if (controller.signal.aborted) {
      throw new Error(`request timed out after ${timeoutMs / 1000} seconds`)
    }
    return response
  } catch (error) {
    // Why: Electron and Node report AbortError differently; keep deadline logs stable.
    if (controller.signal.aborted) {
      throw new Error(`request timed out after ${timeoutMs / 1000} seconds`)
    }
    throw error
  } finally {
    clearTimeout(timeout)
  }
}

function feedbackRequestBodyInit(body: FeedbackSubmitBody): Pick<RequestInit, 'body' | 'headers'> {
  if (!body.diagnosticBundle && !body.images?.length) {
    return {
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Retry the feedback submission with a higher `timeoutMs` only if the payload is legitimately large (attachments).
  2. Reduce attachment size/count so the request completes within the 60s attachment deadline.
  3. Check network connectivity; a consistently timing-out endpoint indicates a server-side or connectivity problem, not a client bug.

Example fix

// before
const res = await postFeedback(url, body)  // 10s default, times out on big payload

// after
const res = await postFeedback(url, body, FEEDBACK_ATTACHMENT_REQUEST_TIMEOUT_MS, readResponse)
Defensive patterns

Strategy: retry

Validate before calling

// For large payloads, request a longer deadline up front.
const timeoutMs = hasImages ? FEEDBACK_ATTACHMENT_REQUEST_TIMEOUT_MS : FEEDBACK_REQUEST_TIMEOUT_MS
await postFeedback(url, body, timeoutMs, readResponse)

Type guard

function isTimeoutError(e: unknown): boolean {
  return e instanceof Error && /^request timed out after/.test(e.message)
}

Try / catch

try {
  await postFeedback(url, body, timeoutMs, readResponse)
} catch (e) {
  if (e instanceof Error && /^request timed out after/.test(e.message)) {
    // only retry once, with a longer deadline and/or smaller payload
    await postFeedback(url, body, timeoutMs * 2, readResponse)
    return
  }
  throw e
}

Prevention

When it happens

Trigger: `net.fetch` plus `readResponse` took longer than `timeoutMs` (10s for plain feedback, 60s for image attachments), and the AbortController fired during or just after body parsing.

Common situations: Slow or saturated feedback endpoint; large image attachments exceeding 60s on a poor link; an endpoint that streams a body slowly enough that the deadline elapses mid-read.

Understand the failure class

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/b1e600719f16b3f6. Report an issue: GitHub.