linshenkx/prompt-optimizer · error · Error
S3 object not found: ${normalized}
Error message
S3 object not found: ${normalized} What it means
GetObject retried on transient errors; a clean NoSuchKey/404 from S3 is converted to this explicit not-found error (distinct from the retryable path). The requested backup object does not exist under the computed key.
Source
Thrown at packages/ui/src/utils/remote-backup.ts:1626
updatedAt: new Date().toISOString(),
contentType,
}
}
async get(path: string): Promise<ArrayBuffer> {
const normalized = normalizeObjectPath(path)
let lastError: unknown
for (let attempt = 1; attempt <= S3_DOWNLOAD_RETRY_ATTEMPTS; attempt += 1) {
try {
const response = await this.client.send(new GetObjectCommand({
Bucket: this.config.bucket,
Key: this.keyForPath(normalized),
}))
return await s3BodyToArrayBuffer(response.Body)
} catch (error) {
if (isS3NotFoundError(error)) {
throw new Error(`S3 object not found: ${normalized}`, { cause: error })
}
lastError = error
if (!isRetryableS3DownloadError(error) || attempt === S3_DOWNLOAD_RETRY_ATTEMPTS) {
break
}
await sleep(S3_DOWNLOAD_RETRY_BASE_DELAY_MS * attempt)
}
}
throw new Error(`S3 download failed: ${s3ErrorMessage(lastError)}`, { cause: lastError })
}
async list(prefix: string): Promise<RemoteObjectEntry[]> {
const entries: RemoteObjectEntry[] = []
let continuationToken: string | undefined
try {
do {View on GitHub (pinned to 3e677b1d9f)
Solutions
- Confirm the object exists under <prefix>/<path> in the configured bucket
- If you changed the prefix setting, restore the previous prefix value so keys resolve again
- list() first and match by path before get()
Example fix
// before
const buf = await store.get(entry.path)
// after
const entries = await store.list('')
const match = entries.find(e => e.path === entry.path)
if (!match) throw new Error('entry no longer on remote')
const buf = await store.get(entry.path) Defensive patterns
Strategy: validation
Validate before calling
const entries = await store.list('')
if (!entries.some(e => e.path === path)) throw new Error('no such remote object') Try / catch
try { await store.get(path) } catch (e) { if ((e as Error).message.startsWith('S3 object not found')) return null; throw e } Prevention
- Never change the prefix setting and expect old backups to resolve
- List-then-get when restoring
When it happens
Trigger: get(path) where the object was deleted, the prefix config changed (keyForPath maps path under config.prefix), or the backup was written under a different prefix/bucket.
Common situations: Changing the prefix setting after backups were made; restoring from a wiped bucket; listing from one bucket and downloading from another.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Evaluation model key must not be empty.
- Function mode must not be empty.
- Sub mode must not be empty.
- ${modelKey}
- ${templateId}
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/c920f2fde05ebc56.
Report an issue: GitHub.