linshenkx/prompt-optimizer · error · Error
S3 download returned an unsupported response body
Error message
S3 download returned an unsupported response body
What it means
Thrown by s3BodyToArrayBuffer when the S3 (or S3-compatible) response body cannot be coerced to bytes: it handles empty bodies, ArrayBuffer, Uint8Array, and streaming chunked bodies, and throws this error for anything else (e.g. a Blob or string body).
Source
Thrown at packages/ui/src/utils/remote-backup.ts:701
const chunks: Uint8Array[] = []
let total = 0
for (;;) {
const { done, value } = await reader.read()
if (done) break
if (!value) continue
chunks.push(value)
total += value.byteLength
}
const bytes = new Uint8Array(total)
let offset = 0
for (const chunk of chunks) {
bytes.set(chunk, offset)
offset += chunk.byteLength
}
return bytes.buffer
}
throw new Error('S3 download returned an unsupported response body')
}
const isS3NotFoundError = (error: unknown): boolean => {
const value = error as {
name?: string
Code?: string
code?: string
$metadata?: { httpStatusCode?: number }
}
return value?.$metadata?.httpStatusCode === 404 ||
value?.name === 'NotFound' ||
value?.name === 'NoSuchKey' ||
value?.Code === 'NoSuchKey' ||
value?.code === 'NoSuchKey'
}
const s3ErrorMessage = (error: unknown): string =>
(error as Error)?.message || String(error)View on GitHub (pinned to 3e677b1d9f)
Solutions
- Inspect the actual body type at runtime (body?.constructor?.name) to identify the unexpected shape
- Convert before calling: use response.arrayBuffer() for fetch responses, orSdkStreamMixin/transform in AWS SDK v3 to normalize Body
- Pin or upgrade the S3 SDK to a version whose body shape the helper supports
- If using an S3-compatible gateway, ensure it returns standard binary octet-stream responses
Example fix
// before
const body = await s3.send(new GetObjectCommand({ Key })).Body // unknown shape
// after - normalize fetch-style responses first
const resp = await fetch(signedUrl)
const body = await resp.arrayBuffer() // ArrayBuffer is always accepted
const buf = await s3BodyToArrayBuffer(body) Defensive patterns
Strategy: type-guard
Validate before calling
const normalizeS3Body = async (body: unknown): Promise<ArrayBuffer | Uint8Array | null> => {
if (!body) return null
if (body instanceof Blob) return await body.arrayBuffer()
if (typeof body === 'string') return new TextEncoder().encode(body)
return (body as ArrayBuffer | Uint8Array) ?? null
} Type guard
const isSupportedS3Body = ( body: unknown, ): body is ArrayBuffer | Uint8Array => body instanceof ArrayBuffer || body instanceof Uint8Array
Try / catch
try {
const buf = await s3BodyToArrayBuffer(body)
} catch (error) {
if ((error as Error).message.includes('unsupported response body')) {
const resp = (body as unknown as { transformToByteArray?: () => Promise<Uint8Array> })
if (typeof resp.transformToByteArray === 'function') {
return await s3BodyToArrayBuffer(await resp.transformToByteArray())
}
}
throw error
} Prevention
- Normalize SDK v3 streams with transformToByteArray before passing bodies
- Pin the AWS SDK version in package.json to avoid body-shape drift
- Use response.arrayBuffer() for fetch-based pre-signed URL downloads
When it happens
Trigger: S3 client (or custom endpoint/proxy like MinIO, R2, or an API gateway) returning the object body as a Blob, ReadableStream of non-Uint8Array chunks, string, or an SDK version whose body type is not handled; head requests or pre-signed URL fetches returning unexpected representations.
Common situations: Switching S3 SDK versions where getObject().Body changed shape (v2 stream vs v3 sdkStreamMixin); browser fetch returning a Blob because response.blob() was called instead of arrayBuffer(); S3-compatible backends (MinIO/Ceph) with differing response encodings; middleware converting streams.
Related errors
- S3 metadata lookup failed: ${s3ErrorMessage(error)}
- S3 upload failed: ${s3ErrorMessage(error)}
- S3 list failed: ${s3ErrorMessage(error)}
- ${context}: ${response.status} ${message || response.statusT
- Desktop remote storage returned an unsupported binary payloa
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/e5163201e9abed60.
Report an issue: GitHub.