{"record":{"id":"7b4c97acf8eea2aa","repo":"mem0ai/mem0","slug":"http-resp-status-detail-7b4c97","errorCode":null,"errorMessage":"HTTP ${resp.status}: ${detail}","messagePattern":"HTTP (.+?): (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/openclaw/backend/platform.ts","lineNumber":84,"sourceCode":"      try {\n        const body = (await resp.json()) as Record<string, unknown>;\n        detail =\n          ((body.detail ?? body.message ?? JSON.stringify(body)) as string) ??\n          resp.statusText;\n      } catch {\n        detail = resp.statusText;\n      }\n      throw new APIError(path, detail);\n    }\n    if (!resp.ok) {\n      let detail: string = resp.statusText;\n      try {\n        const body = (await resp.json()) as Record<string, unknown>;\n        detail = (body.detail ?? body.message ?? resp.statusText) as string;\n      } catch {\n        /* ignore */\n      }\n      throw new Error(`HTTP ${resp.status}: ${detail}`);\n    }\n    if (resp.status === 204) {\n      return {};\n    }\n    return resp.json();\n  }\n\n  async add(\n    content?: string,\n    messages?: Record<string, unknown>[],\n    opts: AddOptions = {},\n  ): Promise<Record<string, unknown>> {\n    const payload: Record<string, unknown> = {};\n\n    if (messages) {\n      payload.messages = messages;\n    } else if (content) {\n      payload.messages = [{ role: \"user\", content }];","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/integrations/openclaw/backend/platform.ts#L66-L102","documentation":"Generic HTTP failure thrown by PlatformBackend._request when the Mem0 platform API (api.mem0.ai) returns any non-OK status other than 400/401/404 (e.g. 403, 409, 422, 429, 5xx). The message embeds the HTTP status code plus the server-provided detail from the JSON body (body.detail or body.message) or the status text when the body is not JSON. Requests carry a 30s AbortSignal timeout and a Token Authorization header.","triggerScenarios":"Calling any PlatformBackend method (add, search, delete, deleteEntities, etc.) against api.mem0.ai where the response status is not ok and not 400/401/404: 403 (wrong region/baseUrl), 422 (payload validation), 429 (rate limit), 500/502/503 (server errors). Also a custom baseUrl pointing at a proxy or non-Mem0 service that returns HTML, in which case detail falls back to resp.statusText.","commonSituations":"Rate limiting during bulk memory imports; expired API key that is syntactically valid but revoked (403 instead of 401); wrong baseUrl (EU vs US platform); transient 5xx during platform incidents; proxy/gateway between the agent and api.mem0.ai rewriting responses.","solutions":["Read the embedded status code: 429 means back off and retry with exponential delay; 5xx is transient — retry once; 403/422 are request problems — fix the API key scope or payload.","Verify the API key is active and the baseUrl matches your Mem0 platform region in openclaw.json (plugins section).","For 422, log the full detail string — it names the exact invalid field sent to /v1/memories/ or /v2/entities/.","Check status.mem0.ai for ongoing incidents if 5xx persists."],"exampleFix":"// before\nawait backend.add(content);\n// unhandled: HTTP 429: Too Many Requests\n\n// after\ntry {\n  await backend.add(content);\n} catch (err) {\n  const msg = err instanceof Error ? err.message : String(err);\n  const status = Number(msg.match(/^HTTP (\\d+):/)?.[1]);\n  if (status === 429 || status >= 500) {\n    await new Promise((r) => setTimeout(r, 2000));\n    return backend.add(content); // retry once\n  }\n  throw err;\n}","handlingStrategy":"retry","validationCode":"function classifyHttpError(err: unknown): { status?: number; retryable: boolean } {\n  const msg = err instanceof Error ? err.message : String(err);\n  const m = msg.match(/^HTTP (\\d+):/);\n  if (!m) return { retryable: false };\n  const status = Number(m[1]);\n  return { status, retryable: status === 429 || status >= 500 };\n}","typeGuard":"function isHttpError(err: unknown): err is Error & { message: string } {\n  return err instanceof Error && /^HTTP \\d+:/.test(err.message);\n}","tryCatchPattern":"try {\n  await backend.add(content);\n} catch (err) {\n  const { status, retryable } = classifyHttpError(err);\n  if (retryable) { await sleep(2000); return backend.add(content); }\n  if (status === 403) throw new Error('API key lacks access or wrong baseUrl region');\n  throw err;\n}","preventionTips":["Confirm baseUrl matches your Mem0 platform region before deploying.","Wrap bulk imports with rate-limit-aware retries (429 backoff).","Log the full message — the embedded server detail names the invalid field for 422s."],"tags":["http","network","api","platform-mode","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}