invoke-ai/InvokeAI · error · ExternalProviderRequestError
DashScope response missing output: {data}
Error message
DashScope response missing output: {data} What it means
The AlibabaCloud DashScope provider calls _parse_sync_response after a synchronous multimodal-generation request. It expects the JSON body to contain an 'output' object (the standard DashScope envelope). If 'output' is absent or not a dict, the provider cannot extract choices/images and raises ExternalProviderRequestError to surface the malformed response (with the raw data) to the caller.
Source
Thrown at invokeai/app/services/external_generation/providers/alibabacloud.py:221
if status == "SUCCEEDED":
return self._parse_async_response(output, request, request_id)
if status in ("FAILED", "UNKNOWN"):
message = output.get("message", "Unknown error")
raise ExternalProviderRequestError(f"DashScope task {task_id} failed: {message}")
self._logger.debug("DashScope task %s status: %s (%.0fs elapsed)", task_id, status, elapsed)
time.sleep(_TASK_POLL_INTERVAL)
def _parse_sync_response(
self,
data: dict[str, object],
request: ExternalGenerationRequest,
request_id: str | None,
) -> ExternalGenerationResult:
"""Parse the synchronous multimodal-generation response."""
output = data.get("output")
if not isinstance(output, dict):
raise ExternalProviderRequestError(f"DashScope response missing output: {data}")
choices = output.get("choices")
if not isinstance(choices, list):
raise ExternalProviderRequestError(f"DashScope response missing choices: {data}")
images: list[ExternalGeneratedImage] = []
for choice in choices:
if not isinstance(choice, dict):
continue
message = choice.get("message")
if not isinstance(message, dict):
continue
content = message.get("content")
if not isinstance(content, list):
continue
for part in content:
if not isinstance(part, dict):
continueView on GitHub (pinned to 0b6a024f2f)
Solutions
- Log the full response body in the message to identify what DashScope actually returned (the error already embeds {data})
- Verify external_alibabacloud_base_url points at the correct DashScope endpoint (e.g. https://dashscope-intl.aliyuncs.com) and not a proxy that alters payloads
- Confirm the model_id is in _SYNC_MODELS so the sync endpoint is the right API for that model
- Check DashScope account status/quota — some throttled/failed responses come back 200 with a non-standard body
- Upgrade InvokeAI in case the provider was updated for a DashScope schema change
Example fix
# before
output = data.get("output")
if not isinstance(output, dict):
raise ExternalProviderRequestError(f"DashScope response missing output: {data}")
# after
output = data.get("output")
if output is None and isinstance(data.get("code"), str):
raise ExternalProviderRequestError(
f"DashScope API error {data.get('code')}: {data.get('message')}"
)
if not isinstance(output, dict):
raise ExternalProviderRequestError(f"DashScope response missing output: {data}") Defensive patterns
Strategy: type-guard
Validate before calling
import requests
def precheck(base_url: str, api_key: str) -> None:
r = requests.get(f"{base_url.rstrip('/')}/api/v1/models", headers={"Authorization": f"Bearer {api_key}"}, timeout=10)
r.raise_for_status() Type guard
def has_output(data: dict) -> bool:
return isinstance(data.get("output"), dict) Try / catch
try:
result = provider.generate(request)
except ExternalProviderRequestError as e:
if "missing output" in str(e):
log.error("DashScope returned a non-standard envelope: %s", e)
raise Prevention
- Point external_alibabacloud_base_url at an official DashScope endpoint, not a rewriting proxy
- Log full provider response bodies when generation fails
- Keep the provider updated for DashScope schema changes
- Confirm model_id is supported on the sync endpoint
When it happens
Trigger: POST to /api/v1/services/aigc/multimodal-generation/generation returns 200 but the JSON body lacks an 'output' key, or 'output' is null/list/string — e.g. an API error body, a proxy/WAF HTML or JSON error page, or a DashScope schema change.
Common situations: Using a custom external_alibabacloud_base_url pointing at a gateway that rewrites responses; DashScope returning an error envelope with only 'code'/'message' while still returning HTTP 200; region mismatch (dashscope-intl vs dashscope.cn endpoints) returning unexpected bodies; API version drift.
Related errors
- DashScope response missing choices: {data}
- DashScope request failed with status {response.status_code}
- DashScope async response missing results: {output}
- DashScope async response contained no images: {output}
- Mode '{request.mode}' requires an init image for {request.mo
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/9d3e285015d2187c.
Report an issue: GitHub.