thedotmack/claude-mem · warning
Backfill marker read failed; treating backfill as complete t
Error message
Backfill marker read failed; treating backfill as complete to avoid duplicate sends
What it means
isBackfillComplete() reads the marker file via readJsonSafe, which already maps missing or corrupt-JSON files to null; this catch fires only on hard IO errors (EACCES, EPERM, EIO). Because PostHog events cannot be selectively deleted, the fail-safe default is 'backfill complete' — skip it — since a telemetry gap is preferred over duplicate sends.
Source
Thrown at src/services/telemetry/backfill.ts:168
* backfilled installs re-run and pick up the enriched rollup keys — without it,
* the one-shot marker would pin them forever to whatever shipped when they
* first backfilled (the read_tokens / tokens_saved_vs_naive series would only
* ever reach fresh installs).
*
* A corrupt marker file still counts as complete: a marker was written at some
* point, and duplicate sends are worse than a gap (PostHog data cannot be
* selectively deleted). A marker missing the `version` field is a legacy
* version-1 marker.
*/
function isBackfillComplete(): boolean {
try {
const marker = readJsonSafe<Partial<BackfillMarker> | null>(getBackfillMarkerPath(), null);
if (marker === null) return false;
const version = typeof marker.version === 'number' ? marker.version : 1;
return version >= BACKFILL_VERSION;
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
logger.warn('SYSTEM', 'Backfill marker read failed; treating backfill as complete to avoid duplicate sends', {}, err);
return true;
}
}
function writeBackfillMarker(marker: BackfillMarker): void {
const dataDir = resolveDataDir();
mkdirSync(dataDir, { recursive: true });
writeFileSync(getBackfillMarkerPath(), JSON.stringify(marker, null, 2) + '\n');
}
/**
* Per-day anonymous activity rollups, bucketed by UTC day. Only whole UTC
* days inside `installDay <= day <= lastFullDay` are included, comparing
* day strings (YYYY-MM-DD compares lexicographically) — never raw epochs, so
* no partial day can ever ship. Rows below PROJECT_EPOCH_FLOOR are ignored.
*
* Each query block is independently best-effort (a missing table/column on an
* older install skips that block's keys, never throws) — same pattern asView on GitHub (pinned to e2d1df569a)
Solutions
- Fix read permissions on the marker file inside the claude-mem data dir
- If the file was hand-edited, verify it is valid JSON with jq
- If the marker is truly lost and duplicate analytics are acceptable, delete it so the deterministic backfill reruns
- Otherwise take no action — the historical backfill is simply skipped
Defensive patterns
Strategy: fallback
Prevention
- Keep the data dir readable and writable by the service user
- Exclude the data dir from antivirus and backup file locks
- Never hand-edit the marker; delete it to force a deterministic rerun
When it happens
Trigger: The marker file exists but is unreadable: permission changes, the file locked by antivirus or backup software (common on Windows), a failing disk, or exotic filesystem errors.
Common situations: Data dir restored with wrong ownership; enterprise AV holding files; data dir on a NAS.
Related errors
- Telemetry historical backfill delivery errored; will retry o
- Telemetry: corrupt telemetry.json; treating as no recorded c
- Backfill failed: ${error instanceof Error ? error.message :
- Chroma unavailable before write; leaving documents unsynced
- Telemetry: WSL detection failed; reporting is_wsl=false
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/1a49df31842a0a53.
Report an issue: GitHub.