{"record":{"id":"9d3e285015d2187c","repo":"invoke-ai/InvokeAI","slug":"dashscope-response-missing-output-data","errorCode":null,"errorMessage":"DashScope response missing output: {data}","messagePattern":"DashScope response missing output: (.+?)","errorType":"exception","errorClass":"ExternalProviderRequestError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/external_generation/providers/alibabacloud.py","lineNumber":221,"sourceCode":"            if status == \"SUCCEEDED\":\n                return self._parse_async_response(output, request, request_id)\n            if status in (\"FAILED\", \"UNKNOWN\"):\n                message = output.get(\"message\", \"Unknown error\")\n                raise ExternalProviderRequestError(f\"DashScope task {task_id} failed: {message}\")\n\n            self._logger.debug(\"DashScope task %s status: %s (%.0fs elapsed)\", task_id, status, elapsed)\n            time.sleep(_TASK_POLL_INTERVAL)\n\n    def _parse_sync_response(\n        self,\n        data: dict[str, object],\n        request: ExternalGenerationRequest,\n        request_id: str | None,\n    ) -> ExternalGenerationResult:\n        \"\"\"Parse the synchronous multimodal-generation response.\"\"\"\n        output = data.get(\"output\")\n        if not isinstance(output, dict):\n            raise ExternalProviderRequestError(f\"DashScope response missing output: {data}\")\n\n        choices = output.get(\"choices\")\n        if not isinstance(choices, list):\n            raise ExternalProviderRequestError(f\"DashScope response missing choices: {data}\")\n\n        images: list[ExternalGeneratedImage] = []\n        for choice in choices:\n            if not isinstance(choice, dict):\n                continue\n            message = choice.get(\"message\")\n            if not isinstance(message, dict):\n                continue\n            content = message.get(\"content\")\n            if not isinstance(content, list):\n                continue\n            for part in content:\n                if not isinstance(part, dict):\n                    continue","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/external_generation/providers/alibabacloud.py#L203-L239","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\noutput = data.get(\"output\")\nif not isinstance(output, dict):\n    raise ExternalProviderRequestError(f\"DashScope response missing output: {data}\")\n# after\noutput = data.get(\"output\")\nif output is None and isinstance(data.get(\"code\"), str):\n    raise ExternalProviderRequestError(\n        f\"DashScope API error {data.get('code')}: {data.get('message')}\"\n    )\nif not isinstance(output, dict):\n    raise ExternalProviderRequestError(f\"DashScope response missing output: {data}\")","handlingStrategy":"type-guard","validationCode":"import requests\ndef precheck(base_url: str, api_key: str) -> None:\n    r = requests.get(f\"{base_url.rstrip('/')}/api/v1/models\", headers={\"Authorization\": f\"Bearer {api_key}\"}, timeout=10)\n    r.raise_for_status()","typeGuard":"def has_output(data: dict) -> bool:\n    return isinstance(data.get(\"output\"), dict)","tryCatchPattern":"try:\n    result = provider.generate(request)\nexcept ExternalProviderRequestError as e:\n    if \"missing output\" in str(e):\n        log.error(\"DashScope returned a non-standard envelope: %s\", e)\n    raise","preventionTips":["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"],"tags":["dashscope","api-response","schema-mismatch","external-provider"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}