TencentCloud/TencentDB-Agent-Memory · error

Backend API error ${res.statusCode}: ${data}

Error message

Backend API error ${res.statusCode}: ${data}

What it means

BackendClient.post performs a raw Node http/https POST to the context-offload backend and rejects the returned Promise with `Backend API error <statusCode>: <body>` whenever the response status is missing or outside 200-299. Unlike the offload-client warnings, this is a real rejection: callers awaiting post() will see a thrown Error containing the status code and up to the full response body for diagnostics.

Source

Thrown at MemoryCore/src/offload/backend-client.ts:328

          method: "POST",
          headers: reqHeaders,
          ...(isHttps ? { rejectUnauthorized: false } : {}),
        },
        (res) => {
          let data = "";
          res.on("data", (chunk: Buffer) => {
            data += chunk.toString();
          });
          res.on("end", () => {
            clearTimeout(timer);
            const durationMs = Date.now() - startMs;

            if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
              this.logger.warn(
                `[context-offload] HTTP <<< ${path}: ${res.statusCode} ${res.statusMessage} (${durationMs}ms) body=${data.slice(0, 500)}`,
              );
              reject(new Error(`Backend API error ${res.statusCode}: ${data}`));
              return;
            }

            try {
              const parsed = JSON.parse(data) as T;
              this.logger.debug?.(
                `[context-offload] HTTP <<< ${path}: ${res.statusCode} (${durationMs}ms, ${data.length} bytes)`,
              );
              resolve(parsed);
            } catch {
              reject(new Error(`Backend response JSON parse error: ${data.slice(0, 500)}`));
            }
          });
        },
      );

      req.on("error", (err: Error) => {
        clearTimeout(timer);
        const durationMs = Date.now() - startMs;

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Inspect the status code and body embedded in the error message — the body usually contains the backend's own error explanation.
  2. 401/403 → set/rotate the apiKey passed to BackendClient so the Authorization header is sent.
  3. 404 → verify the backend base URL and endpoint path in the client configuration.
  4. 5xx/429 → check backend service health/logs and add retry with backoff around post() calls.
  5. Ensure callers of post() wrap awaits in try/catch, since this rejection propagates (unlike the fire-and-forget offload-client paths).

Example fix

// before: unhandled rejection on non-2xx
await backendClient.post("/store", payload);
// after: catch and degrade gracefully
try {
  await backendClient.post("/store", payload);
} catch (err) {
  logger.warn(`context-offload store skipped: ${err instanceof Error ? err.message : err}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!backendBaseUrl) throw new Error("backend base URL not configured");
if (!apiKey) logger.warn("no API key set — backend will likely return 401");
try { new URL(`${backendBaseUrl}/store`); } catch { throw new Error("invalid backend URL"); }

Try / catch

try {
  const res = await backendClient.post<T>(path, payload);
  // use res
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  const status = /Backend API error (\d+)/.exec(msg)?.[1];
  if (status === "401" || status === "403") {
    logger.error(`backend auth failed (${status}) — check API key`);
  } else {
    logger.warn(`backend post failed, continuing without offload: ${msg}`);
  }
}

Prevention

When it happens

Trigger: Any BackendClient.post() call whose HTTP response is non-2xx: 401 when Authorization Bearer apiKey is absent/wrong, 404 when the backend base URL or path is wrong, 400 on malformed payload to /store or report endpoints, 429 rate limiting, or 5xx backend errors. Also fires if statusCode is undefined (malformed response).

Common situations: Backend service not deployed at the configured URL (ECONNREFUSED is separate, but 404 indicates wrong path); missing BACKEND_API_KEY so Authorization header is skipped and server returns 401; backend rejecting large /store payloads; corporate proxy returning 403/502; userIdFn/taskIdFn producing headers the backend refuses.

Related errors


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