{"record":{"id":"64782e4bf603258e","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"upstream-request-failed-64782e","errorCode":null,"errorMessage":"Upstream request failed","messagePattern":"Upstream request failed","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"MemoryProxy/src/handler.ts","lineNumber":426,"sourceCode":"      };\n      if (forwardTimeoutMs > 0) {\n        retryFetchOpts.signal = AbortSignal.timeout(forwardTimeoutMs);\n      }\n      upstreamResp = await fetch(target.retryTarget.url, retryFetchOpts);\n      if (upstreamResp.ok) {\n        pipe.info(\"RETRY_SUCCESS\", `Retry returned ${upstreamResp.status}`);\n      } else {\n        pipe.error(\"RETRY_FAILED\", `Retry returned ${upstreamResp.status}`);\n      }\n      return { resp: upstreamResp, retried: true };\n    } catch (retryErr: unknown) {\n      if (isRateLimitExceededError(retryErr)) throw retryErr;\n      if (retryErr instanceof DOMException && retryErr.name === \"TimeoutError\") {\n        pipe.error(\"RETRY_FORWARD\", `Timeout after ${forwardTimeoutMs / 1000}s`);\n      } else {\n        pipe.error(\"RETRY_FORWARD\", retryErr);\n      }\n      throw new Error(\"Upstream request failed\");\n    }\n  }\n\n  if (forwardFailed && !shouldRetry) {\n    throw new Error(\"Upstream request failed\");\n  }\n\n  if (!upstreamResp) {\n    throw new Error(\"No upstream response available\");\n  }\n\n  return { resp: upstreamResp, retried: false };\n}\n\n/** Main handler for POST /v1/chat/completions (OpenAI compat). */\nexport async function handleChatCompletions(\n  c: Context,\n  config: ProxyConfig,","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryProxy/src/handler.ts#L408-L444","documentation":"The OpenAI-style handler.ts forwardWithRetry mirrors the Anthropic one: when the final retry attempt fails (excluding rate-limit errors that must propagate), the cause is logged via pipe.error('RETRY_FORWARD', ...) and a generic Error('Upstream request failed') is thrown. The generic message intentionally hides the underlying timeout/network detail from callers.","triggerScenarios":"Every forward attempt to the upstream LLM provider failed within the retry loop — final attempt threw (network error, reset, or TimeoutError after forwardTimeoutMs), or returned a retryable failure that then exhausted attempts.","commonSituations":"Provider outage, aggressive forwardTimeoutMs for slow completions, corporate proxy blocking egress, upstream 5xx storms exhausting the retry budget.","solutions":["Read the RETRY_FORWARD log entry emitted just before the throw to identify timeout vs network error","Increase forwardTimeoutMs if timeouts occur on long generations","Verify egress connectivity/proxy settings from the proxy host to the upstream provider","Enable longer/backoff retry or circuit-breaking upstream failover if available"],"exampleFix":"// before\nthrow new Error(\"Upstream request failed\");\n// after\nthrow new Error(\"Upstream request failed\", { cause: retryErr }); // preserve timeout/network detail for callers","handlingStrategy":"retry","validationCode":"const reachable = await fetch(upstreamHost, { method: 'HEAD', signal: AbortSignal.timeout(3000) }).then(r => r.status < 500).catch(() => false);\nif (!reachable) throw new Error(`upstream ${upstreamHost} unreachable before forwarding`);","typeGuard":"function isUpstreamRequestFailed(e: unknown): boolean {\n  return e instanceof Error && e.message === 'Upstream request failed';\n}","tryCatchPattern":"try {\n  return await forwardWithRetry(req, pipe);\n} catch (e) {\n  if (isUpstreamRequestFailed(e) && !isRateLimitExceededError(e)) {\n    await backoff(retryCount++);\n    return forwardWithRetry(req, pipe);\n  }\n  throw e;\n}","preventionTips":["Correlate with the RETRY_FORWARD log to distinguish timeout vs network error","Tune forwardTimeoutMs against measured upstream latency","Monitor egress/proxy health from the proxy host","Cap retry storms with backoff and circuit breaking"],"tags":["network","retry","upstream","proxy"],"backgroundTag":"upstream-request-failed","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}