{"record":{"id":"427d4bc59b34e011","repo":"thedotmack/claude-mem","slug":"sync-hub-push-response-requires-decimal-string-he","errorCode":null,"errorMessage":"sync hub push: response requires decimal-string head_seq/projected_seq","messagePattern":"sync hub push: response requires decimal-string head_seq/projected_seq","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/CloudSync.ts","lineNumber":984,"sourceCode":"    }\n    if (!res.ok) {\n      const body = (await res.text().catch(() => '')).slice(0, 200);\n      throw new Error(`sync hub push ${res.status}: ${body}`);\n    }\n    let parsed: unknown;\n    try {\n      parsed = await res.json();\n    } catch {\n      throw new Error('sync hub push: response is not JSON');\n    }\n    const acked = (parsed as { acked?: unknown } | null)?.acked;\n    if (!Array.isArray(acked)) {\n      throw new Error('sync hub push: response missing acked array');\n    }\n    const headSeq = (parsed as { head_seq?: unknown }).head_seq;\n    const projectedSeq = (parsed as { projected_seq?: unknown }).projected_seq;\n    if (typeof headSeq !== 'string' || typeof projectedSeq !== 'string') {\n      throw new Error('sync hub push: response requires decimal-string head_seq/projected_seq');\n    }\n    assertCanonicalDecimal(headSeq);\n    assertCanonicalDecimal(projectedSeq);\n    const validatedAcked = acked.map((value, index): AckedOp => {\n      if (!value || typeof value !== 'object' || Array.isArray(value)) {\n        throw new Error(`sync hub push: acked[${index}] must be an object`);\n      }\n      const item = value as Record<string, unknown>;\n      if (\n        typeof item.id !== 'string'\n        || typeof item.kind !== 'string'\n        || (item.origin_local_id !== null && typeof item.origin_local_id !== 'string')\n        || typeof item.entity_rev !== 'string'\n        || typeof item.operation_sha256 !== 'string'\n        || typeof item.seq !== 'string'\n      ) {\n        throw new Error(`sync hub push: malformed acked[${index}]`);\n      }","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/sync/CloudSync.ts#L966-L1002","documentation":"Thrown when head_seq or projected_seq on the push response is not a string (typeof check fails), before assertCanonicalDecimal validates their canonical form. Like the status endpoint, sequence fields must be decimal strings to preserve uint64 precision across JSON.","triggerScenarios":"The hub returned head_seq/projected_seq as numbers, omitted one, or sent null in the push response. Subsequent code (assertCanonicalDecimal) would also reject non-canonical strings.","commonSituations":"Hub version serializing sequences as numbers; field renamed/missing after a hub update; a proxy altering the response; hub bug emitting null under error.","solutions":["Log the raw parsed push response to identify which field is mistyped.","Ensure the hub emits head_seq and projected_seq as canonical decimal strings.","Align hub and client protocol v2 versions so response shapes match.","If persistently wrong, report to the hub operator and avoid re-pushing until fixed (dedup is safe)."],"exampleFix":"// before: hub emits numbers in push ack\n// {\"acked\":[...],\"head_seq\":42,\"projected_seq\":42}\n// after: hub emits decimal strings\n// {\"acked\":[...],\"head_seq\":\"42\",\"projected_seq\":\"42\"}","handlingStrategy":"validation","validationCode":null,"typeGuard":"function isPushBadDecimalFields(e: unknown): boolean {\n  return e instanceof Error && /sync hub push: response requires decimal-string head_seq\\/projected_seq/i.test(e.message);\n}","tryCatchPattern":"try { await cloudSync.pushOps(ops); }\ncatch (e) { if (isPushBadDecimalFields(e)) { markHubMisconfigured(e.message); return; } throw e; }","preventionTips":["Ensure the hub returns head_seq and projected_seq as canonical decimal strings in push responses.","Align hub and client protocol v2 versions so response field shapes match.","Contract-test push responses for decimal-string sequences.","Re-push is safe (hub dedup) if the response was rejected, but fix the hub to stop recurrence."],"tags":["cloud-sync","push","hub","serialization","decimal-string"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}