{"record":{"id":"c6d639da0aa6a7f4","repo":"thedotmack/claude-mem","slug":"sync-hub-status-response-requires-protocol-versio","errorCode":null,"errorMessage":"sync hub status: response requires protocol_version 2","messagePattern":"sync hub status: response requires protocol_version 2","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":670,"sourceCode":"      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      }\n      this.hubStatus = {\n        checkedAt,\n        reachable: true,\n        epoch,","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/sync/CloudSync.ts#L652-L688","documentation":"The sync-hub status protocol requires protocol_version === 2. probeHubStatus rejects any other version with 'sync hub status: response requires protocol_version 2'. This prevents the client from interpreting an incompatible hub protocol.","triggerScenarios":"Hub reports protocol_version 1 (or 3+), or omits the field, because the hub and client were built against different protocol revisions.","commonSituations":"Upgraded client talking to an old hub (or vice versa) after a deployment skew, self-hosted hub fork pinned to an older protocol, environment variable or build flag selecting a legacy protocol.","solutions":["Upgrade the hub (or the client) so both sides speak sync-hub protocol_version 2.","If a deployment skew is detected, roll back the more recently deployed side until versions match.","Check hub release notes for protocol_version changes and migration steps.","For testing, update mock hub fixtures to emit protocol_version: 2."],"exampleFix":"// before (hub)\nres.json({ head_seq, projected_seq, epoch });\n// after\nres.json({ protocol_version: 2, epoch, head_seq, projected_seq });","handlingStrategy":"validation","validationCode":"const res = await fetch(hubUrl + '/status');\nconst parsed = await res.json();\nif (parsed?.protocol_version !== 2) {\n  throw new Error(`hub speaks protocol_version ${parsed?.protocol_version}; client requires 2 — upgrade hub`);\n}","typeGuard":"function isProtocolV2(v: unknown): v is { protocol_version: 2 } & Record<string, unknown> {\n  return typeof v === 'object' && v !== null && (v as any).protocol_version === 2;\n}","tryCatchPattern":"try {\n  const status = await cloudSync.statusWithHubProbe();\n} catch (e) {\n  if (e.message === 'sync hub status: response requires protocol_version 2') {\n    logger.error('sync-hub protocol skew detected; halting sync until hub is upgraded');\n    disableSyncUntilVersionsMatch();\n  } else throw e;\n}","preventionTips":["Version-check the hub at startup and fail fast on protocol skew","Deploy client and hub protocol changes together (no rolling skew)","Keep protocol_version negotiation explicit rather than guessing","Test mock hubs with the exact protocol_version the client requires"],"tags":["protocol","version-mismatch","sync-hub"],"backgroundTag":"unsupported-operation","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}