thedotmack/claude-mem · error

sync hub push: response requires decimal-string head_seq/pro

Error message

sync hub push: response requires decimal-string head_seq/projected_seq

What it means

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.

Source

Thrown at src/services/sync/CloudSync.ts:984

    }
    if (!res.ok) {
      const body = (await res.text().catch(() => '')).slice(0, 200);
      throw new Error(`sync hub push ${res.status}: ${body}`);
    }
    let parsed: unknown;
    try {
      parsed = await res.json();
    } catch {
      throw new Error('sync hub push: response is not JSON');
    }
    const acked = (parsed as { acked?: unknown } | null)?.acked;
    if (!Array.isArray(acked)) {
      throw new Error('sync hub push: response missing acked array');
    }
    const headSeq = (parsed as { head_seq?: unknown }).head_seq;
    const projectedSeq = (parsed as { projected_seq?: unknown }).projected_seq;
    if (typeof headSeq !== 'string' || typeof projectedSeq !== 'string') {
      throw new Error('sync hub push: response requires decimal-string head_seq/projected_seq');
    }
    assertCanonicalDecimal(headSeq);
    assertCanonicalDecimal(projectedSeq);
    const validatedAcked = acked.map((value, index): AckedOp => {
      if (!value || typeof value !== 'object' || Array.isArray(value)) {
        throw new Error(`sync hub push: acked[${index}] must be an object`);
      }
      const item = value as Record<string, unknown>;
      if (
        typeof item.id !== 'string'
        || typeof item.kind !== 'string'
        || (item.origin_local_id !== null && typeof item.origin_local_id !== 'string')
        || typeof item.entity_rev !== 'string'
        || typeof item.operation_sha256 !== 'string'
        || typeof item.seq !== 'string'
      ) {
        throw new Error(`sync hub push: malformed acked[${index}]`);
      }

View on GitHub (pinned to d768ba3643)

Solutions

  1. Log the raw parsed push response to identify which field is mistyped.
  2. Ensure the hub emits head_seq and projected_seq as canonical decimal strings.
  3. Align hub and client protocol v2 versions so response shapes match.
  4. If persistently wrong, report to the hub operator and avoid re-pushing until fixed (dedup is safe).

Example fix

// before: hub emits numbers in push ack
// {"acked":[...],"head_seq":42,"projected_seq":42}
// after: hub emits decimal strings
// {"acked":[...],"head_seq":"42","projected_seq":"42"}
Defensive patterns

Strategy: validation

Type guard

function isPushBadDecimalFields(e: unknown): boolean {
  return e instanceof Error && /sync hub push: response requires decimal-string head_seq\/projected_seq/i.test(e.message);
}

Try / catch

try { await cloudSync.pushOps(ops); }
catch (e) { if (isPushBadDecimalFields(e)) { markHubMisconfigured(e.message); return; } throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: Hub version serializing sequences as numbers; field renamed/missing after a hub update; a proxy altering the response; hub bug emitting null under error.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/427d4bc59b34e011. Report an issue: GitHub.