HKUDS/DeepTutor · error · ValueError

DashScope response missing `output` (request_id={getattr(res

Error message

DashScope response missing `output` (request_id={getattr(resp, 'request_id', '')})

What it means

After a successful (200) DashScope call, _parse_response requires an output attribute on the response; if output is None it raises ValueError including request_id for correlation. A missing output means the SDK returned an envelope without results — typically SDK/service contract drift or a truncated response.

Source

Thrown at deeptutor/services/embedding/adapters/dashscope_native.py:186

    def _raise_on_error(self, resp: Any, model_name: str) -> None:
        status_code = getattr(resp, "status_code", None)
        if status_code is None or status_code == HTTPStatus.OK:
            return
        code = getattr(resp, "code", "") or ""
        message = getattr(resp, "message", "") or ""
        request_id = getattr(resp, "request_id", "") or ""
        raise RuntimeError(
            f"DashScope MultiModalEmbedding call failed: "
            f"status={status_code}, code={code}, message={message}, "
            f"model={model_name}, request_id={request_id}"
        )

    def _parse_response(
        self, resp: Any, model_name: str, request: EmbeddingRequest
    ) -> EmbeddingResponse:
        output = getattr(resp, "output", None)
        if output is None:
            raise ValueError(
                f"DashScope response missing `output` (request_id={getattr(resp, 'request_id', '')})"
            )

        # `output` is dict-like in the SDK.
        if isinstance(output, dict):
            raw = output.get("embeddings") or []
        else:
            raw = getattr(output, "embeddings", None) or []

        embeddings: List[List[float]] = []
        for item in raw:
            if isinstance(item, dict):
                vec = item.get("embedding")
            else:
                vec = getattr(item, "embedding", None)
            if vec is None:
                continue
            embeddings.append(list(vec))

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Pin/upgrade dashscope to the version the adapter was built against (check project extras)
  2. Retry once — transient envelopes occur; keep request_id for tracing
  3. If persistent, capture the raw SDK response and report with request_id to DashScope support

Example fix

# before
resp = await adapter.embed(req)  # ValueError: missing `output`
# after
for attempt in range(2):
    try:
        resp = await adapter.embed(req)
        return resp
    except ValueError as e:
        if "missing `output`" in str(e) and attempt == 0:
            continue
        raise
Defensive patterns

Strategy: retry

Try / catch

try:
    return await adapter.embed(req)
except ValueError as e:
    if "missing `output`" in str(e):
        await asyncio.sleep(1)
        return await adapter.embed(req)
    raise

Prevention

When it happens

Trigger: DashScope returns 200 but the response object lacks output — SDK version drift changing the response shape, gateway interference, or an upstream anomaly; hit inside _embed_multimodal/_embed_text parsing.

Common situations: Upgrading the dashscope SDK to a version with a different response layout; proxies or serializing middlewares stripping attributes; intermittent upstream incidents.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/7b5646b393b2ad9f. Report an issue: GitHub.