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
- Inspect the status code and body embedded in the error message — the body usually contains the backend's own error explanation.
- 401/403 → set/rotate the apiKey passed to BackendClient so the Authorization header is sent.
- 404 → verify the backend base URL and endpoint path in the client configuration.
- 5xx/429 → check backend service health/logs and add retry with backoff around post() calls.
- 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
- Always await post() inside try/catch — it rejects on any non-2xx status.
- Configure the apiKey before constructing BackendClient so Authorization is always sent.
- Parse the status code out of the error message to branch on 401 vs 429 vs 5xx.
- Add retry-with-backoff only for transient statuses (429, 5xx); fail fast on 4xx.
- Validate the backend URL with new URL() at startup to catch path typos early.
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
- CORE_UPSTREAM_ERROR
- ${TAG} ${path} HTTP ${resp.status}${detail ? `: ${detail.sli
- ${TAG} ${path} envelope error ${env.code}: ${env.message ??
- invalid model_id
- <resp.text or "HTTP {resp.status_code} returned a non-JSON r
AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01).
Data as JSON: /api/errors/37cbe36cc1644b7c.
Report an issue: GitHub.