overleaf/overleaf · error
Blob ${hash} is not backed up for project ${projectId} - use
Error message
Blob ${hash} is not backed up for project ${projectId} - use --force to delete anyway What it means
Before deleting a misplaced backup blob, canDeleteBlob calls verifyBlobs to confirm the blob is properly backed up at the correct location. If verification throws (the blob is NOT backed up), the script raises this error so the deletion is aborted — deleting would leave the blob with no backup at all. --force overrides this check.
Source
Thrown at services/history-v1/storage/scripts/remove_backup_blobs_from_wrong_path.mjs:180
if (historyId === projectId) {
throw new Error(
`Project ID and history ID are the same for ${projectId} - use --force to delete anyway`
)
}
// TODO: fix assert.postgresId to handle integers better and then stop coercing to string below
assert.postgresId(
`${historyId}`,
`History ID ${historyId} does not appear to be for a postgres project`
)
try {
await verifyBlobs(`${historyId}`, [hash])
} catch (error) {
if (args.verbose) {
console.error(error)
}
throw new Error(
`Blob ${hash} is not backed up for project ${projectId} - use --force to delete anyway`
)
}
}
if (!args.commit) {
console.log('DRY RUN: provide --commit to perform operations')
}
if (args.force) {
console.log(
'WARNING: --force is enabled, blobs will be deleted regardless of backup status'
)
await setTimeout(5_000)
}
let deleted = 0
let errors = 0View on GitHub (pinned to 28ad3b03b7)
Solutions
- Run a backup for the project so the blob exists in the backup store, then retry.
- Re-run with --force only if you accept permanent loss of that blob's backup.
- Check backup bucket configuration (S3/GCS creds, bucket name) used by the backup persistor.
- Confirm the hash/historyId pair is correct — the blob may be backed up under a different project.
Example fix
// before node remove_backup_blobs_from_wrong_path.mjs --project-id X --hash h1 // after node verify_backup_blob.mjs --historyId H --hashes h1 # confirm backup exists first node remove_backup_blobs_from_wrong_path.mjs --project-id X --hash h1
Defensive patterns
Strategy: validation
Validate before calling
try {
await verifyBlobs(historyId, [hash])
console.log(`${hash} backed up; safe to delete`)
} catch {
console.error(`${hash} NOT backed up; aborting delete`)
} Try / catch
try {
await canDeleteBlob(projectId, hash)
} catch (err) {
if (err.message.includes('not backed up')) {
console.warn(`Skipping ${hash}: no backup exists`)
} else throw err
} Prevention
- Ensure backup jobs complete before running cleanup scripts.
- Run verify_backup_blob.mjs on each hash before deleting.
- Check backup bucket env config for the persistor.
- Never combine --force with unverified hashes.
When it happens
Trigger: verifyBlobs(historyId, [hash]) throws because the blob hash is absent from the backup bucket for the given history id — e.g. backup never ran, backup bucket misconfigured, or hash belongs to a different project.
Common situations: Partial backup coverage (backup job interrupted); backup bucket name/region mismatch in env; running cleanup before the initial backup completed; hashes collected from the wrong history.
Related errors
- Blob ${blobHash} not found in project ${historyId}
- Blob ${blobHash} not found in backup
- Blob ${hash} could not be loaded for history ${historyId}
- No history ID found for project ${projectId}, skipping
- Project ID and history ID are the same for ${projectId} - us
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/2765538173408b81.
Report an issue: GitHub.