CherryHQ/cherry-studio · error · Error
Image generation produced ${urls.length} URL(s) but all down
Error message
Image generation produced ${urls.length} URL(s) but all downloads failed What it means
Error "Image generation produced ${urls.length} URL(s) but all downloads failed" thrown in CherryHQ/cherry-studio.
Source
Thrown at src/main/ai/provider/custom/tasks/imageGenerationJobHandler.ts:224
const fileManager = application.get('FileManager')
const files: FileEntry[] = []
for (const url of urls) {
if (signal.aborted) throw createAbortError('Image generation aborted')
const downloaded = await downloadImageAsBase64(url)
if (!downloaded) continue
files.push(
await fileManager.createInternalEntry({
source: 'base64',
data: `data:${downloaded.media_type || 'image/png'};base64,${downloaded.data}`,
cleanupPolicy
})
)
}
// The remote generation succeeded (it returned URLs); surfacing a hard failure
// when none could be downloaded avoids reporting a paid generation as an empty,
// silent success. A partial failure still returns what we have, with a warning.
if (files.length === 0) {
throw new Error(`Image generation produced ${urls.length} URL(s) but all downloads failed`)
}
if (files.length < urls.length) {
logger.warn('Some generated image downloads failed', { requested: urls.length, persisted: files.length })
}
return files
}
/**
* Best-effort delete of temp image-input `file_entry` copies. Called by AiService
* to clean up inputs it created when the job enqueue fails before the job owns
* them. Once a job is enqueued its inputs are held by `job_file_ref`, and the
* cleanup pass reclaims them when the job row is pruned — there is no ad-hoc
* post-job delete (file-entry-cleanup.md §4.1/§5.1). Idempotent and non-throwing.
*/
export async function deleteImageInputEntries(ids: ReadonlyArray<string | undefined>): Promise<void> {
const present = ids.filter((id): id is string => Boolean(id))
if (present.length === 0) return
const fileManager = application.get('FileManager')View on GitHub (pinned to 726446b54c)
Solutions
- Check network connectivity to the CDN hosts serving the image URLs and retry.
- Verify the URLs have not expired — some providers sign URLs with short TTLs; download immediately after generation.
- Inspect per-download errors in the job logs to see whether failures are 403/expired-signature or timeouts.
Example fix
Download images as soon as the task completes, and on failure surface the underlying HTTP status: fetch(url) then check response.ok before reading the blob.
When it happens
Trigger: The remote generation succeeded and returned one or more image URLs, but every downloadAndPersistImageUrls attempt failed, leaving zero persisted files.
Common situations: Caused by expired/signed URL expiry, network failures, or blocked CDN hosts when fetching generated images. A hard failure is surfaced so a paid generation is not reported as an empty silent success; partial failures still return the files that downloaded, with a warning.
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/c7ee969409191f50.
Report an issue: GitHub.