{"record":{"id":"e2ebce574b9441e5","repo":"thedotmack/claude-mem","slug":"sync-hub-status-response-must-be-an-object","errorCode":null,"errorMessage":"sync hub status: response must be an object","messagePattern":"sync hub status: response must be an object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":606,"sourceCode":"        },\n        signal: AbortSignal.timeout(this.requestTimeoutMs),\n      });\n      checkedAt = Date.now();\n      const syncMode = response.headers.get('X-Sync-Mode');\n      if (syncMode !== null || response.ok) this.emitSyncMode(syncMode);\n      if (!response.ok) {\n        const body = (await response.text().catch(() => '')).slice(0, 200);\n        throw new Error(`sync hub status ${response.status}: ${body}`);\n      }\n\n      let parsed: unknown;\n      try {\n        parsed = await response.json();\n      } catch {\n        throw new Error('sync hub status: response is not JSON');\n      }\n      if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n        throw new Error('sync hub status: response must be an object');\n      }\n      const record = parsed as Record<string, unknown>;\n      if (record.protocol_version !== 2) {\n        throw new Error('sync hub status: response requires protocol_version 2');\n      }\n      if (\n        typeof record.epoch !== 'string'\n        || typeof record.head_seq !== 'string'\n        || typeof record.projected_seq !== 'string'\n      ) {\n        throw new Error('sync hub status: response requires decimal-string epoch/head_seq/projected_seq');\n      }\n      const epoch = assertCanonicalDecimal(record.epoch, { positive: true });\n      const headSeq = assertCanonicalDecimal(record.head_seq);\n      const projectedSeq = assertCanonicalDecimal(record.projected_seq);\n      if (compareCanonicalDecimals(projectedSeq, headSeq) > 0) {\n        throw new Error('sync hub status: projected_seq exceeds head_seq');\n      }","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L588-L624","documentation":"Thrown when the parsed JSON status body is not a non-null, non-array object (parsed is falsy, typeof !== 'object', or Array.isArray). The hub must return a JSON object; arrays, primitives, or null are rejected before any field is read.","triggerScenarios":"The hub returned valid JSON but it was an array (e.g. a list endpoint by mistake), a JSON primitive (string/number/boolean), or null. Typically a routing mistake where a different endpoint answered /v1/sync/status.","commonSituations":"hubUrl routes to a generic collection endpoint that returns an array; a load balancer returning a JSON-formatted health string; the hub deployed a version where /v1/sync/status returns a different shape.","solutions":["Log the parsed value's type to confirm what the hub actually returned.","Confirm hubUrl and the request path are exactly /v1/sync/status on the correct hub.","Verify hub protocol_version compatibility — the client expects a status object, not a list.","If the hub changed its response shape, align client and hub versions."],"exampleFix":"// before: hub returns an array for the status route\n// GET /v1/sync/status -> [{\"epoch\":...}]\n// after: hub returns the expected object\n// GET /v1/sync/status -> {\"protocol_version\":2,\"epoch\":\"...\",...}","handlingStrategy":"validation","validationCode":null,"typeGuard":"function isHubStatusNotObject(e: unknown): boolean {\n  return e instanceof Error && /sync hub status: response must be an object/i.test(e.message);\n}","tryCatchPattern":"try { await cloudSync.status(); }\ncatch (e) { if (isHubStatusNotObject(e)) { markHubMisconfigured(e.message); return; } throw e; }","preventionTips":["Pin the hub version to one whose /v1/sync/status returns a JSON object.","Add a contract test asserting the status route returns an object, not an array or primitive.","Ensure the request hits the status route and not a generic collection endpoint."],"tags":["cloud-sync","json","hub","protocol","validation"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}