thedotmack/claude-mem · warning
Cloud sync flush failed; unsynced rows remain queued
Error message
Cloud sync flush failed; unsynced rows remain queued
What it means
The cloud-sync flush loop drains every kind in sequence; any throw is caught here — lastError is recorded, unsynced rows keep their NULL markers so they stay queued, the warning carries the next backoff delay, and scheduleRetry() re-arms the timer. A shutdown detected mid-flush skips the bookkeeping entirely.
Source
Thrown at src/services/sync/CloudSync.ts:538
this.flushing = true;
try {
do {
this.flushAgainRequested = false;
await this.drainContentOutbox();
await this.drainMutations();
for (const kind of KINDS) {
await this.drainKind(kind);
}
} while (this.flushAgainRequested && !this.stopped);
if (this.stopped) return; // shutdown mid-flush — skip success bookkeeping
this.lastFlushAt = Date.now();
this.lastError = null;
this.resetBackoff();
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
this.lastError = err.message;
// Rows stay NULL — retried by the backoff timer below and on next notify().
logger.warn('CLOUD_SYNC', 'Cloud sync flush failed; unsynced rows remain queued', {
retryInMs: this.nextBackoffMs,
}, err);
this.scheduleRetry();
} finally {
this.flushing = false;
}
}
status(): CloudSyncStatus {
return {
configured: this.isConfigured(),
deviceId: this.deviceId,
pending: {
observations: this.countPending('observations'),
summaries: this.countPending('session_summaries'),
prompts: this.countPending('user_prompts'),
mutations: this.countPendingMutations(),
tombstones: this.countPendingTombstones(),View on GitHub (pinned to e2d1df569a)
Solutions
- Check connectivity and credentials for the sync hub; queued rows retry automatically on the backoff timer.
- Re-run the sync configuration if the token expired.
- Inspect status() (lastError) afterwards to confirm the flush recovered.
Defensive patterns
Strategy: retry
Try / catch
try {
for (const kind of KINDS) await drainKind(kind);
} catch (err) {
// rows keep NULL sync markers; re-arm the backoff timer and retry later
scheduleRetry();
} Prevention
- Keep sync credentials fresh; reconfigure before expiry.
- Expect eventual delivery — rows queue and retry on backoff, they are not dropped.
When it happens
Trigger: drainKind throws for any kind — hub 5xx, auth rejection, or network drop — during a flush pass.
Common situations: Expired sync credentials, sync hub outage, or the machine switching networks mid-flush.
Related errors
- cloud sync canonical payload: ${name} must be a non-negative
- cloud sync canonical payload: ${name} must be stored JSON te
- cloud sync canonical payload: ${name} is not valid JSON
- cloud sync canonical payload: ${name} must decode to an arra
- cloud sync canonical payload: ${name} must decode to an obje
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/2ee64570594238c7.
Report an issue: GitHub.