hcengineering/platform · error · Error
${infoFile} could not restore to ${opt.date}. Snapshot is mi
Error message
${infoFile} could not restore to ${opt.date}. Snapshot is missing. What it means
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.
Source
Thrown at server/backup/src/restore.ts:86
skip?: Set<string>
progress?: (progress: number) => Promise<void>
cleanIndexState?: boolean
historyFile?: string
}
): Promise<boolean> {
const infoFile = 'backup.json.gz'
const workspaceId = wsIds.uuid
if (!(await storage.exists(infoFile))) {
ctx.error('file not pressent', { file: infoFile })
throw new Error(`${infoFile} should present to restore`)
}
const backupInfo: BackupInfo = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile(infoFile))).toString())
let snapshots = backupInfo.snapshots
if (opt.date !== -1) {
const bk = backupInfo.snapshots.findIndex((it) => it.date === opt.date)
if (bk === -1) {
ctx.error('could not restore to', { date: opt.date, file: infoFile, workspaceId })
throw new Error(`${infoFile} could not restore to ${opt.date}. Snapshot is missing.`)
}
snapshots = backupInfo.snapshots.slice(0, bk + 1)
} else {
opt.date = snapshots[snapshots.length - 1].date
}
if (backupInfo.domainHashes === undefined) {
backupInfo.domainHashes = {}
}
ctx.info('restore to ', { id: opt.date, date: new Date(opt.date).toDateString() })
const rsnapshots = Array.from(snapshots).reverse()
// Collect all possible domains
const domains = new Set<Domain>()
for (const s of snapshots) {
Object.keys(s.domains).forEach((it) => domains.add(it as Domain))
}
View on GitHub (pinned to 63e28dc964)
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).
Example fix
// before
await restore(ctx, storage, workspaceId, { date: Date.parse('2024-05-01') })
// after
const info = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())
const snap = info.snapshots.find(s => s.date <= Date.parse('2024-05-01'))
await restore(ctx, storage, workspaceId, { date: snap?.date ?? -1 }) Defensive patterns
Strategy: validation
Validate before calling
const info = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())
if (opt.date !== -1 && !info.snapshots.some(s => s.date === opt.date)) {
throw new Error(`date ${opt.date} not in snapshots: ${info.snapshots.map(s => s.date).join(',')}`)
} Try / catch
try {
await restore(ctx, storage, workspaceId, opt)
} catch (err) {
if (err.message.includes('Snapshot is missing')) {
const list = JSON.parse(gunzipSync(new Uint8Array(await storage.loadFile('backup.json.gz'))).toString())
console.error('Available snapshot dates:', list.snapshots.map(s => s.date))
}
throw err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${infoFile} should present to restore
- Low level storage is not available
- Low level storage is not available
- Max retries (${maxRetries}) exceeded while loading chunks fo
- ${infoFile} should present to check
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/7de82b5cf2d34571.
Report an issue: GitHub.