{"record":{"id":"1999b1bd2de53a16","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"offload-client-compaction-returned-response-st","errorCode":null,"errorMessage":"[offload-client] compaction returned ${response.status}","messagePattern":"\\[offload-client\\] compaction returned (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"MemoryCore/src/offload-client/offload-api-client.ts","lineNumber":153,"sourceCode":"      total_tokens: req.totalTokens,\n      message_tokens: req.messageTokens,\n    });\n\n    try {\n      const controller = new AbortController();\n      const timer = setTimeout(() => controller.abort(), this.config.compactionTimeoutMs);\n\n      const response = await fetch(url, {\n        method: \"POST\",\n        headers: this.buildHeaders(),\n        body,\n        signal: controller.signal,\n      });\n\n      clearTimeout(timer);\n\n      if (!response.ok) {\n        this.logger.warn(`[offload-client] compaction returned ${response.status}`);\n        return null;\n      }\n\n      const json = (await response.json()) as any;\n      if (json.code !== 0 || !json.data) {\n        this.logger.warn(`[offload-client] compaction error: ${json.message ?? \"unknown\"}`);\n        return null;\n      }\n\n      return { messages: json.data.messages, report: json.data.report };\n    } catch (err) {\n      this.logger.warn(`[offload-client] compaction failed: ${err}`);\n      return null;\n    }\n  }\n\n  private buildHeaders(): Record<string, string> {\n    return {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/offload-client/offload-api-client.ts#L135-L171","documentation":"OffloadApiClient.compaction POSTs the current conversation to /v2/offload/compact and is documented to return null on timeout/failure so the caller keeps the original uncompressed messages. This warning is logged when the server answers with a non-2xx HTTP status; the method then returns null. Losing compaction degrades token savings but never breaks the conversation.","triggerScenarios":"compaction() is called and fetch() resolves with response.ok === false: 401/403 from invalid apiKey or X-TDAI-Service-Id, 404 from wrong serverUrl or pre-v2 server, 413 when the messages array exceeds server body limits, 5xx when the server's compaction pipeline fails. (Timeout/abort and JSON code!==0 paths log different messages.)","commonSituations":"Offload server down or upgraded to a different API path; credentials rotated without updating OffloadClientConfig; very large context_window conversations producing oversized request bodies; server-side model/backend outage causing 502/503.","solutions":["Read the status code in the warning: fix apiKey/serviceId for 401/403, serverUrl for 404, and check server health/logs for 5xx.","Verify server reachability with checkHealth() before relying on remote compaction.","Confirm the caller handles the null return by falling back to the original messages (the intended contract).","Reduce payload size (send fewer messages or pre-trim) if the status is 413.","Retry after transient 5xx; compaction is idempotent per call."],"exampleFix":"// before: assume compaction always succeeds\nconst result = await client.compaction(req);\nmessages = result!.messages;\n// after: honor the null fallback contract\nconst result = await client.compaction(req);\nif (result) {\n  messages = result.messages;\n} else {\n  logger.warn(\"compaction unavailable, keeping original messages\");\n}","handlingStrategy":"fallback","validationCode":"const health = await client.checkHealth();\nif (!health) {\n  logger.warn(\"offload server down — using local messages without compaction\");\n}","typeGuard":"function isCompactionResult(r: CompactionResult | null): r is CompactionResult {\n  return r !== null && Array.isArray((r as CompactionResult).messages);\n}","tryCatchPattern":"const result = await client.compaction(req).catch(() => null);\nif (isCompactionResult(result)) {\n  messages = result.messages;\n} else {\n  logger.warn(\"compaction unavailable — keeping original messages\");\n}","preventionTips":["Always code the null-return fallback path: keep original messages when compaction returns null.","Health-check the server before long sessions and degrade to local-only mode when it is down.","Watch for 413/429 statuses and cap the messages payload size sent to /v2/offload/compact.","Alert on repeated compaction warnings — they signal server config/credential drift."],"tags":["http","network","compaction","graceful-degradation"],"backgroundTag":"http-non-2xx-response","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}