CherryHQ/cherry-studio · error · Error
Image generation submit for '${sdkConfig.modelId}' returned
Error message
Image generation submit for '${sdkConfig.modelId}' returned neither imageUrls nor a taskId What it means
Error "Image generation submit for '${sdkConfig.modelId}' returned neither imageUrls nor a taskId" thrown in CherryHQ/cherry-studio.
Source
Thrown at src/main/ai/provider/custom/tasks/imageGenerationJobHandler.ts:108
const transport = resolveImageTransport(sdkConfig.providerId, sdkConfig.modelId, sdkConfig.providerSettings)
if (!transport) {
throw new Error(
`Image generation job: no async transport for '${sdkConfig.providerId}' (model '${sdkConfig.modelId}')`
)
}
// No persisted-task resume branch: `recovery: 'abandon'` means a job never
// outlives the process that enqueued it, so every execution starts at submit.
let urls: string[]
const submit = await transport.submit(await buildSubmitInput(input, sdkConfig.modelId, ctx.signal))
if (submit.imageUrls) {
urls = submit.imageUrls
} else if (submit.taskId) {
urls = await pollUntilDone(transport, submit.taskId, ctx)
} else {
// A malformed submit response (neither URLs nor a task id) must fail the
// job rather than silently complete with zero files (a paid no-op).
throw new Error(`Image generation submit for '${sdkConfig.modelId}' returned neither imageUrls nor a taskId`)
}
// Record before local download: the provider invocation completed even if file
// persistence fails. Polling is part of this invocation, not another billable
// call; a successful zero-image response is still an observable invocation.
if (captureContext) {
const completedAt = Date.now()
aiUsageRecordService.recordInvocation({
requestId: `custom-image:${ctx.jobId}`,
context: captureContext,
modality: 'image',
imageCount: urls.length,
metrics: { timeCompletionMs: Math.max(0, completedAt - usageStartedAt) },
completedAt
})
}
// An empty URL list from a *successful* submit/poll (e.g. content moderationView on GitHub (pinned to 726446b54c)
Solutions
- Check the image transport implementation for the model: it must return either imageUrls for synchronous results or a taskId for async polling.
- Verify the provider's image transport response parsing — some providers nest URLs under data[].url or output fields.
- Enable debug logging for the provider transport to inspect the raw submit response and confirm which field carries the result.
Example fix
In the provider's submit response parser, return { imageUrls } or { taskId }; e.g. return { taskId: data.task_id } when the API is asynchronous. When it happens
Trigger: An async image generation transport's submit() resolves with neither imageUrls nor taskId — a malformed vendor response that the job handler cannot act on.
Common situations: Occurs when a custom image provider (DashScope, ModelScope, PPIO, etc.) returns a degraded or unexpected submit response, e.g. content moderation short-circuiting the task or a vendor API schema change. The job fails instead of silently completing with zero files (a paid no-op).
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/25ba893bb845b599.
Report an issue: GitHub.