CherryHQ/cherry-studio · error · Error
Missing modelDescriptor for DashScope model: ${input.modelId
Error message
Missing modelDescriptor for DashScope model: ${input.modelId} What it means
Thrown by `DashScopeTransport.submit` when `input.modelDescriptor` is undefined. The descriptor carries per-model routing (endpoint path, sync/async flag, response family) derived from the registry's `vendorTransport`; without it the transport cannot pick an endpoint or parse the response. This is a wiring invariant, not a user input.
Source
Thrown at src/main/ai/provider/custom/dashscope/dashscopeTransport.ts:381
default:
throw new Error(`Unsupported DashScope image model: ${descriptor.id}`)
}
}
class DashScopeTransport implements ImageGenerationTransport {
private apiKey: string
private baseURL: string
private pendingDescriptors = new Map<string, DashScopeModelDescriptor>()
constructor(settings: DashScopeTransportSettings) {
this.apiKey = settings.apiKey
this.baseURL = settings.imageBaseURL || DEFAULT_DASHSCOPE_IMAGE_BASE_URL
}
async submit(input: ImageGenerationSubmitInput): Promise<{ taskId?: string; imageUrls?: string[] }> {
const descriptor = input.modelDescriptor
if (!descriptor) {
throw new Error(`Missing modelDescriptor for DashScope model: ${input.modelId}`)
}
const body = buildRequestBody(input, descriptor)
const extraHeaders: Record<string, string> = descriptor.isSync ? {} : { 'X-DashScope-Async': 'enable' }
const response = await this.request<DashScopeTaskResult>(descriptor.endpoint, 'POST', body, {
timeout: 120000,
signal: input.signal,
extraHeaders
})
if (descriptor.isSync) {
return { imageUrls: extractImageUrls(response.output, responseFamilyFor(descriptor)) }
}
const taskId = response.output.task_id
if (!taskId) {
throw new DashScopeApiError('DashScope async submit returned no task_id', 0)View on GitHub (pinned to 726446b54c)
Solutions
- Ensure `paintingPipeline.ts` resolves and injects `modelDescriptor` from the registry's `modes[mode].vendorTransport` into the submit input.
- Add a `vendorTransport` entry (endpoint, isSync) for the affected model/mode in the registry.
- Guard upstream: reject model selections whose registry mode has no `vendorTransport` before reaching the transport.
Example fix
// before — submit called with no descriptor
await transport.submit({ modelId, prompt, ... })
// after — pipeline injects the descriptor
await transport.submit({ modelId, prompt, modelDescriptor: { id: modelId, endpoint, isSync }, ... }) Defensive patterns
Strategy: validation
Validate before calling
if (!input.modelDescriptor) {
throw new Error(`No vendorTransport registered for model ${input.modelId} — check the registry's modes[mode].vendorTransport`)
} Type guard
const hasModelDescriptor = (
input: ImageGenerationSubmitInput
): input is ImageGenerationSubmitInput & { modelDescriptor: ImageTransportDescriptor } =>
input.modelDescriptor != null Prevention
- Ensure paintingPipeline.ts always injects modelDescriptor before submit
- Require a vendorTransport entry for every image mode in the registry
- Unit-test that submit throws the descriptor error when the pipeline is bypassed
When it happens
Trigger: The painting pipeline called `submit` without injecting `modelDescriptor` into the `ImageGenerationSubmitInput`; the registry mode for the selected model lacks a `vendorTransport` entry; a code path bypassed `paintingPipeline.ts` which normally populates the descriptor.
Common situations: A new image mode was added to the registry without a `vendorTransport` block; a refactor stopped threading the descriptor through the job payload; a model was selected whose registry entry predates the descriptor mechanism.
Related errors
- DashScope provider requires a non-empty `baseURL`. An empty
- Unsupported DashScope image model: ${descriptor.id}
- 0
- DashScope task ${status.toLowerCase()}
- Task polling timeout
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/12c16cf0b6c83612.
Report an issue: GitHub.