linshenkx/prompt-optimizer · error · Error
Unable to safely analyze remote snapshot assets because ${fa
Error message
Unable to safely analyze remote snapshot assets because ${failures.length} snapshot manifest(s) could not be read. First failure: ${firstFailure.path}: ${firstFailure.message} What it means
Thrown by analyzeRemoteSnapshotAssetCleanup in remote-snapshot-backup.ts after it attempts to read every remote snapshot manifest and collects failures. Because cleanup analysis must classify each snapshot's assets to decide what is safe to delete, an unreadable manifest makes the whole analysis unsafe, so the function aborts with the count and the first failing path/message.
Source
Thrown at packages/ui/src/utils/remote-snapshot-backup.ts:655
const entries = await objectStore.list(joinRemotePath(REMOTE_SNAPSHOT_ROOT, 'snapshots'))
const manifestEntries = entries.filter((entry) => entry.path.endsWith(`/${MANIFEST_FILE_NAME}`))
const manifests: RemoteSnapshotManifest[] = []
const failures: Array<{ path: string; message: string }> = []
for (const entry of manifestEntries) {
try {
manifests.push(parseManifest(await objectStore.getText(entry.path)))
} catch (error) {
failures.push({
path: entry.path,
message: (error as Error).message || String(error),
})
}
}
if (failures.length > 0) {
const firstFailure = failures[0]
throw new Error(
`Unable to safely analyze remote snapshot assets because ${failures.length} snapshot manifest(s) could not be read. First failure: ${firstFailure.path}: ${firstFailure.message}`,
)
}
return manifests
}
const isCleanupCandidateOldEnough = (
entry: Pick<RemoteObjectEntry, 'updatedAt'>,
nowMs: number,
minimumAgeMs: number,
): boolean => {
if (minimumAgeMs <= 0) return true
if (!entry.updatedAt) return false
const updatedAtMs = Date.parse(entry.updatedAt)
return Number.isFinite(updatedAtMs) && nowMs - updatedAtMs >= minimumAgeMs
}
View on GitHub (pinned to 3e677b1d9f)
Solutions
- Check the reported first failure path and message to see whether it is a network/permission problem or corrupted JSON
- Retry the operation if the message indicates a transient network failure
- Repair or remove the broken snapshot entry (delete the orphaned manifest/asset keys for that snapshot) and re-run the analysis
- Verify object-store credentials and bucket policy grant read access to all snapshot prefixes
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate manifest readability before analysis
const manifests = await Promise.all(snapshotIds.map(async (id) => {
try { return await store.get(`snapshots/${id}/manifest.json`) } catch { return null }
}))
if (manifests.some((m) => m === null)) skipCleanup() Type guard
const isReadableManifest = (value: unknown): value is SnapshotManifest => typeof value === 'object' && value !== null && 'id' in value && 'assets' in value
Try / catch
try {
await cleanupRemoteSnapshotAssets(store, onProgress)
} catch (error) {
if (error instanceof Error && error.message.startsWith('Unable to safely analyze')) {
// log and skip cleanup; do not delete anything
} else throw error
} Prevention
- Ensure backups fully complete so manifests are written atomically
- Monitor failed upload jobs and clean up partial snapshots
- Keep bucket credentials valid and scoped to the snapshot prefix
When it happens
Trigger: Calling analyzeRemoteSnapshotAssetCleanup (or cleanupRemoteSnapshotAssets, which calls it first) when one or more snapshot manifest JSON objects on the remote object store are missing, corrupted, truncated, or return access/network errors during listing+get.
Common situations: A previous backup upload was interrupted leaving a partial manifest; the remote bucket was edited/deleted manually; credentials lost read permission on some keys; transient network errors or bucket rate limits during manifest reads.
Related errors
- Result evaluation snapshot testCaseId must match testCase.id
- Compare evaluation requires at least two snapshots.
- Compare snapshot #${index + 1} references unknown testCaseId
- Invalid app backup package manifest
- app backup package is missing manifest.json
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/3d1bd1bcb317382f.
Report an issue: GitHub.