TencentCloud/TencentDB-Agent-Memory · error

No upstream response available

Error message

No upstream response available

What it means

End-state guard in forwardWithRetry: forwarding never produced an upstreamResp, and the earlier forwardFailed/shouldRetry conditions did not throw (i.e. failure bookkeeping and retry bookkeeping disagree). The function cannot return a response, so it throws 'No upstream response available'. This usually signals a logic gap where attempts failed without setting forwardFailed, or retries were scheduled but none produced a response.

Source

Thrown at MemoryProxy/src/anthropicHandler.ts:518

      }
      return { resp: upstreamResp, retried: true };
    } catch (retryErr: unknown) {
      if (isRateLimitExceededError(retryErr)) throw retryErr;
      if (retryErr instanceof DOMException && retryErr.name === "TimeoutError") {
        pipe.error("RETRY_FORWARD", `Timeout after ${forwardTimeoutMs / 1000}s`);
      } else {
        pipe.error("RETRY_FORWARD", retryErr);
      }
      throw new Error("Upstream request failed");
    }
  }

  if (forwardFailed && !shouldRetry) {
    throw new Error("Upstream request failed");
  }

  if (!upstreamResp) {
    throw new Error("No upstream response available");
  }

  return { resp: upstreamResp, retried: false };
}

/** Main handler for POST /v1/messages (Anthropic Messages API). */
export async function handleAnthropicMessages(
  c: Context,
  config: ProxyConfig,
): Promise<Response> {
  const startTime = new Date().toISOString();
  const traceId = uuidv7();

  // ── Early auth ──────────────────────────────────────────────────────────
  // Verify BEFORE parsing the body so a rejected caller never triggers body
  // parsing or the alias-gate. `earlyVerify.userId` is reused later for
  // both the systemUser short-circuit and the normal pipeline.
  const earlyApiKey = extractApiKey(c);

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Log upstreamResp/attempt state at each loop iteration to find the path that exits without a response
  2. Ensure every failed attempt sets forwardFailed (or throws) before the loop can exit
  3. Make this error carry the attempt count and last status for debuggability
  4. Add an invariant test: forwardWithRetry always returns a response or throws one of the two defined errors

Example fix

// before
if (!upstreamResp) throw new Error("No upstream response available");
// after
if (!upstreamResp) throw new Error(`No upstream response available after ${attemptCount} attempts (last=${lastStatus ?? 'none'})`);
Defensive patterns

Strategy: try-catch

Validate before calling

// no meaningful pre-call validation; it is an internal invariant
if (typeof forwardWithRetry !== 'function') throw new Error('handler not initialized');

Type guard

function isNoUpstreamResponse(e: unknown): boolean {
  return e instanceof Error && e.message === 'No upstream response available';
}

Try / catch

try {
  return await forwardWithRetry(req, pipe);
} catch (e) {
  if (isNoUpstreamResponse(e)) {
    // logic/invariant gap, not transient: log full context and fail fast
    pipe.error('NO_UPSTREAM_RESPONSE', e);
    return jsonError(502, 'proxy produced no upstream response');
  }
  throw e;
}

Prevention

When it happens

Trigger: All forward attempts completed without success yet neither forwardFailed nor the retry path triggered a throw — e.g. attempt bookkeeping not updated on some failure path, shouldRetry true but no attempt was actually re-executed, or an empty attempts list.

Common situations: Rare: retry loop refactor leaving upstreamResp unset; non-ok responses treated as retryable without recording failure; streaming responses aborted before assignment.

Related errors


AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01). Data as JSON: /api/errors/d13d84905f006a4d. Report an issue: GitHub.