{"record":{"id":"7de82b5cf2d34571","repo":"hcengineering/platform","slug":"infofile-could-not-restore-to-opt-date-snap","errorCode":null,"errorMessage":"${infoFile} could not restore to ${opt.date}. Snapshot is missing.","messagePattern":"(.+?) could not restore to (.+?)\\. Snapshot is missing\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/backup/src/restore.ts","lineNumber":86,"sourceCode":"    skip?: Set<string>\n    progress?: (progress: number) => Promise<void>\n    cleanIndexState?: boolean\n    historyFile?: string\n  }\n): Promise<boolean> {\n  const infoFile = 'backup.json.gz'\n  const workspaceId = wsIds.uuid\n  if (!(await storage.exists(infoFile))) {\n    ctx.error('file not pressent', { file: infoFile })\n    throw new Error(`${infoFile} should present to restore`)\n  }\n  const backupInfo: BackupInfo = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile(infoFile))).toString())\n  let snapshots = backupInfo.snapshots\n  if (opt.date !== -1) {\n    const bk = backupInfo.snapshots.findIndex((it) => it.date === opt.date)\n    if (bk === -1) {\n      ctx.error('could not restore to', { date: opt.date, file: infoFile, workspaceId })\n      throw new Error(`${infoFile} could not restore to ${opt.date}. Snapshot is missing.`)\n    }\n    snapshots = backupInfo.snapshots.slice(0, bk + 1)\n  } else {\n    opt.date = snapshots[snapshots.length - 1].date\n  }\n\n  if (backupInfo.domainHashes === undefined) {\n    backupInfo.domainHashes = {}\n  }\n  ctx.info('restore to ', { id: opt.date, date: new Date(opt.date).toDateString() })\n  const rsnapshots = Array.from(snapshots).reverse()\n\n  // Collect all possible domains\n  const domains = new Set<Domain>()\n  for (const s of snapshots) {\n    Object.keys(s.domains).forEach((it) => domains.add(it as Domain))\n  }\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/backup/src/restore.ts#L68-L104","documentation":"restore() in server/backup reads backup.json.gz and looks up the requested snapshot by its exact `date` timestamp via findIndex. When `opt.date` is not -1 and no snapshot has a matching `date` value, it throws this error to refuse restoring to a nonexistent point in time. It is a guard against silently restoring to a different snapshot than requested.","triggerScenarios":"Calling restore(storage, { date: <timestamp> }) where the timestamp does not exactly equal the `date` field of any snapshot in backupInfo.snapshots. Dates must match exactly — not 'closest before' or a human-readable date string.","commonSituations":"Passing a JS Date's milliseconds from the wrong clock/timezone, guessing a date instead of listing snapshots first (backupList prints valid snapshot dates), restoring into a workspace whose backup.json.gz is from an older/different backup set, or off-by-one rounding when computing the timestamp.","solutions":["Run backupList (or inspect backup.json.gz) to enumerate valid snapshot `date` values and pick an exact one.","Pass -1 as opt.date to restore to the latest snapshot instead of a specific date.","Verify the timestamp is in milliseconds and matches the stored value exactly (no seconds/ms confusion).","Confirm you are pointing restore at the backup storage that actually contains the snapshot (correct workspace/bucket/credentials)."],"exampleFix":"// before\nawait restore(ctx, storage, workspaceId, { date: Date.parse('2024-05-01') })\n\n// after\nconst info = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())\nconst snap = info.snapshots.find(s => s.date <= Date.parse('2024-05-01'))\nawait restore(ctx, storage, workspaceId, { date: snap?.date ?? -1 })","handlingStrategy":"validation","validationCode":"const info = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())\nif (opt.date !== -1 && !info.snapshots.some(s => s.date === opt.date)) {\n  throw new Error(`date ${opt.date} not in snapshots: ${info.snapshots.map(s => s.date).join(',')}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await restore(ctx, storage, workspaceId, opt)\n} catch (err) {\n  if (err.message.includes('Snapshot is missing')) {\n    const list = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())\n    console.error('Available snapshot dates:', list.snapshots.map(s => s.date))\n  }\n  throw err\n}","preventionTips":["Always list snapshots (backupList) and pick an exact `date` value before restoring.","Use date: -1 to restore to the latest snapshot when a specific point isn't required.","Keep timestamps in UTC milliseconds end-to-end; never round or convert through Date strings.","Log the available snapshot dates alongside this error for faster diagnosis."],"tags":["backup","restore","snapshot-not-found"],"backgroundTag":"backup-snapshot-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}