{"record":{"id":"77e74c07413ef823","repo":"hcengineering/platform","slug":"infofile-has-no-snapshot-at-date","errorCode":null,"errorMessage":"${infoFile} has no snapshot at ${date}","messagePattern":"(.+?) has no snapshot at (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/backup/src/check.ts","lineNumber":77,"sourceCode":"  blobs: BlobCheckResult\n  ok: boolean\n}\n\nasync function resolveSnapshots (\n  storage: BackupStorage,\n  date: number\n): Promise<{ backupInfo: BackupInfo, snapshots: BackupSnapshot[], date: number }> {\n  const infoFile = 'backup.json.gz'\n  if (!(await storage.exists(infoFile))) {\n    throw new Error(`${infoFile} should present to check`)\n  }\n  const backupInfo: BackupInfo = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile(infoFile))).toString())\n\n  let snapshots = backupInfo.snapshots\n  if (date !== -1) {\n    const bk = backupInfo.snapshots.findIndex((it) => it.date === date)\n    if (bk === -1) {\n      throw new Error(`${infoFile} has no snapshot at ${date}`)\n    }\n    snapshots = backupInfo.snapshots.slice(0, bk + 1)\n  } else {\n    date = snapshots[snapshots.length - 1]?.date ?? -1\n  }\n  return { backupInfo, snapshots, date }\n}\n\n/**\n * Checks whether all documents recorded in a backup are present, and unchanged, in the given\n * workspace's document domains, and whether every backed-up blob's content exists in blob\n * storage (see {@link checkWorkspaceBlobs}).\n *\n * This is read-only: nothing is uploaded, removed, or otherwise modified in either the workspace\n * or the backup. It is meant as a diagnostic to run before trusting a backup (or after a restore)\n * — to find out if the workspace is missing data the backup has, without acting on it.\n *\n * Account domains (person/socialId) are skipped, since they live in the account database rather","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/backup/src/check.ts#L59-L95","documentation":"resolveSnapshots throws this Error when a specific date filter is requested (date !== -1) but no snapshot in backup.json.gz has that exact date. The check tool can only resolve snapshots by exact timestamp match, not nearest-before.","triggerScenarios":"Calling the backup check flow with a date parameter that does not exactly equal any snapshot's date field in the manifest, causing findIndex to return -1.","commonSituations":"Hand-copying a timestamp with wrong precision (ms vs s) or timezone shifts; requesting a date between snapshots; a snapshot with that date was pruned from a newer manifest.","solutions":["List snapshot dates from backup.json.gz and pass an exact existing timestamp.","Use date = -1 to check against the latest snapshot.","Check millisecond precision — snapshot dates are epoch millis.","Use a manifest from a backup run that actually contains the desired snapshot."],"exampleFix":"// resolve by exact stored date\n// before\nawait resolved(ctx, storage, 1699999999) // seconds, no match\n// after\nawait resolved(ctx, storage, 1699999999000) // exact snapshot date in ms, or -1","handlingStrategy":"validation","validationCode":"// resolve an exact snapshot date from the manifest first\nconst info = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())\nif (!info.snapshots.some((s: any) => s.date === requestedDate)) {\n  throw new Error(`No snapshot at ${requestedDate}; use an exact snapshot date or -1`)\n}","typeGuard":"function hasSnapshot(manifest: { snapshots: { date: number }[] }, date: number): boolean {\n  return date === -1 || manifest.snapshots.some(s => s.date === date)\n}","tryCatchPattern":"try {\n  await runCheck(ctx, storage, date)\n} catch (err) {\n  if (err instanceof Error && err.message.includes('has no snapshot at')) {\n    // list available dates and let the user choose\n  } else throw err\n}","preventionTips":["Use date = -1 unless a specific snapshot is truly required.","Store timestamps in epoch milliseconds end to end; never seconds.","Build tooling UI that lists snapshot dates instead of free-text input.","Remember matching is exact — no nearest-before semantics."],"tags":["backup","snapshot","date-mismatch"],"backgroundTag":"snapshot-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}