yikart/AiToEarn · error · Error
No images were generated
Error message
No images were generated
What it means
ShareModal's image download path throws this Error when generateShareImageBlobs (invoked with appTitle/appUrl/shareUrl/expiresAt) returns an empty or null blob array, meaning no share images could be rendered. The throw is caught by the surrounding handler which shows an error to the user instead of downloading files.
Source
Thrown at project/aitoearn-web/src/components/Chat/Share/ShareModal.tsx:394
console.error('Failed to generate share link:', err)
toast.error('Failed to generate share link')
return
}
finally {
setGeneratingLink(false)
}
}
setGeneratingImage(true)
try {
const blobs = await generateImageFromMessages(selectedMessages, user?.name, {
appTitle: t('appName'),
appUrl: t('appUrl'),
shareUrl: link || undefined,
expiresAt: expiresAt || undefined,
})
if (!blobs || blobs.length === 0)
throw new Error('No images were generated')
// 直接下载
for (let i = 0; i < blobs.length; i++) {
const blob = blobs[i]
const a = document.createElement('a')
const url = URL.createObjectURL(blob)
a.href = url
a.download
= blobs.length === 1
? `aitoearn_conversation_${taskId}.png`
: `aitoearn_${taskId}_${i + 1}.png`
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(url)
}
toast.success(t('download'))
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Ensure all images inside the share node are loaded (await image decode/onload) before generating blobs
- Serve share images via the same-origin OSS proxy (getOssProxyPath) to avoid canvas tainting
- Verify the share preview DOM node is mounted and has non-zero size when generating
- Log the generator's return value to find why blobs is empty; add a retry
Example fix
// before
const blobs = await generateShareImageBlobs({ ... })
if (!blobs || blobs.length === 0)
throw new Error('No images were generated')
// after
const blobs = await generateShareImageBlobs({ ... })
if (!blobs || blobs.length === 0)
throw new Error(`No images were generated (link=${link}, expiresAt=${expiresAt})`) Defensive patterns
Strategy: validation
Validate before calling
const node = document.querySelector('[data-share-card]')
if (!node || node.clientWidth === 0) throw new Error('share node not rendered')
await Promise.all(Array.from(node.querySelectorAll('img')).map(img => img.decode?.() ?? Promise.resolve())) Type guard
function isBlobArray(v: unknown): v is Blob[] {
return Array.isArray(v) && v.length > 0 && v.every(b => b instanceof Blob)
} Try / catch
try {
const blobs = await generateShareImageBlobs({...})
if (!isBlobArray(blobs)) throw new Error('No images were generated')
} catch (e) {
toast.error(t('share.downloadFailed'))
} Prevention
- Await all image loads inside the share node before rendering to canvas
- Proxy cross-origin images via getOssProxyPath to avoid canvas tainting
- Verify the share preview is mounted and visible when generating
- Test share download in headless/older browsers
When it happens
Trigger: Clicking the download action in ShareModal when the canvas/html-to-image generation produced zero blobs — e.g. the share preview node was not mounted, contained cross-origin tainted images, or rendering silently failed.
Common situations: Share dialog opened before QR/preview images finished loading; cross-origin images tainting the canvas so toBlob/serialization yields nothing; browser rendering failure in headless or older browsers; shareUrl/expiry state empty.
Related errors
- Failed to generate combined image
- S3DownloadFileFailed
- imageSize must be one of 1K, 2K, or 4K
- image aspectRatio must use WIDTH:HEIGHT
- image aspectRatio must use positive integer WIDTH:HEIGHT
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/64b407aa8e70c774.
Report an issue: GitHub.