{"record":{"id":"9ab72f5d8e3af189","repo":"JuliusBrussee/caveman","slug":"local-learn-snapshot-has-no-valid-generated-at-at","errorCode":null,"errorMessage":"local learn snapshot has no valid generated_at at ${snapshotPath}","messagePattern":"local learn snapshot has no valid generated_at at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":10066,"sourceCode":"// from the current learn snapshot. Titles, suggestions, evidence, file paths,\n// and payload text never leave the machine. Empty snapshots are sent so stale\n// rows for this user are removed server-side.\nasync function syncLocalPracticeFindings(cfg: Config): Promise<PracticeSyncOutcome> {\n  const snapshotPath = join(cavemanHome(), \"reports\", \"caveman-learn.json\");\n  let raw: Record<string, unknown>;\n  try {\n    raw = JSON.parse(readFileSync(snapshotPath, \"utf8\")) as Record<string, unknown>;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { kind: \"no_snapshot\" };\n    throw new Error(`local learn snapshot is unreadable at ${snapshotPath}`);\n  }\n\n  if (!Array.isArray(raw.sinks)) {\n    throw new Error(`local learn snapshot has no sinks array at ${snapshotPath}`);\n  }\n  const observed = typeof raw.generated_at === \"string\" ? new Date(raw.generated_at) : null;\n  if (!observed || Number.isNaN(observed.valueOf())) {\n    throw new Error(`local learn snapshot has no valid generated_at at ${snapshotPath}`);\n  }\n  const sessions = typeof raw.sessions_scanned === \"number\" && Number.isFinite(raw.sessions_scanned)\n    ? Math.max(0, Math.trunc(raw.sessions_scanned))\n    : 0;\n  const counter = (value: unknown) =>\n    typeof value === \"number\" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;\n\n  const findings = raw.sinks\n    .filter((sink): sink is Record<string, unknown> =>\n      !!sink && typeof sink === \"object\" && !Array.isArray(sink))\n    .filter((sink) => typeof sink.practice_id === \"string\" && sink.practice_id.length > 0)\n    .map((sink) => ({\n      sink_id: typeof sink.sink_id === \"string\" ? sink.sink_id : \"\",\n      practice_id: sink.practice_id as string,\n      basis: \"inferred\",\n      tokens_per_turn: counter(sink.tokens_per_turn),\n      tokens_per_day_rate: counter(sink.tokens_per_day_rate),\n      sessions_scanned: sessions,","sourceCodeStart":10048,"sourceCodeEnd":10084,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L10048-L10084","documentation":"The learn snapshot at ~/.caveman/reports/caveman-learn.json parsed as JSON but its generated_at field is missing or not a valid timestamp. Without a trustworthy generation time the snapshot cannot be freshness-checked, so syncing local practice findings is refused rather than sending data of unknown age.","triggerScenarios":"Thrown at packages/cli/src/index.ts:9221 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Regenerate the snapshot via `caveman learn` so generated_at is written correctly","Check for manual edits or partial writes to caveman-learn.json"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}