HKUDS/DeepTutor · error · ValueError

Cannot parse embeddings from response JSON. Top-level keys={

Error message

Cannot parse embeddings from response JSON. Top-level keys={keys}, expected one of: data/embedding/embeddings/result/output.

What it means

The response parsed as a JSON object, contained no "error" key, but none of the known vector-bearing shapes (data / embedding / embeddings / result / output) were present or non-empty. This means the endpoint answered with an unexpected schema — usually a chat-completion object, a usage-only object, or a gateway status page.

Source

Thrown at deeptutor/services/embedding/adapters/openai_compatible.py:141

        if isinstance(output, dict):
            if isinstance(output.get("data"), list):
                candidates.append(output["data"])
            if isinstance(output.get("embeddings"), list):
                candidates.append(output["embeddings"])

        for c in candidates:
            if not c:
                continue
            first = c[0]
            # list of {"embedding":[...]}
            if isinstance(first, dict) and "embedding" in first:
                return [item.get("embedding") or [] for item in c if isinstance(item, dict)]
            # list of vectors [[...], ...]
            if isinstance(first, list):
                return [item for item in c if isinstance(item, list)]

        keys = sorted(list(data.keys()))
        raise ValueError(
            "Cannot parse embeddings from response JSON. "
            f"Top-level keys={keys}, expected one of: data/embedding/embeddings/result/output."
        )

    _MAX_RETRIES = 5
    _RETRY_BACKOFF = 1.0
    _RATE_LIMIT_BACKOFF = 5.0

    def _should_send_dimensions(self, model_name: str | None) -> bool:
        """Decide whether to attach `dimensions` to the request payload.

        Tri-state semantics driven by `self.send_dimensions`:
        * ``True``  -> always send (user explicitly opted in)
        * ``False`` -> never send (user explicitly opted out)
        * ``None``  -> auto: send for known model families that accept the
          OpenAI-style ``dimensions`` parameter — OpenAI ``text-embedding-3*``,
          Qwen3-Embedding, Qwen3-VL-Embedding.
        """

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Inspect the reported Top-level keys= list to identify what the endpoint actually returned
  2. Fix base_url to end with the embeddings path (e.g. https://host/v1/embeddings)
  3. Confirm the configured model is an embedding model, not a chat model
  4. If a legitimate new schema, extend _extract_embeddings_from_response with the new key

Example fix

# before
base_url = "https://my-gateway.example.com/v1"  # chat endpoint, returns chat JSON
# after
base_url = "https://my-gateway.example.com/v1/embeddings"
Defensive patterns

Strategy: validation

Validate before calling

import httpx
async def check_embeddings_endpoint(base_url, api_key, model):
    r = await httpx.AsyncClient().post(base_url, json={"input": ["ping"], "model": model},
                                      headers={"Authorization": f"Bearer {api_key}"})
    data = r.json()
    assert not (isinstance(data, dict) and "error" in data), data
    assert any(k in data for k in ("data", "embedding", "embeddings", "result", "output")), data

Type guard

null

Try / catch

try:
    resp = await adapter.embed(req)
except ValueError as e:
    if "Cannot parse embeddings" in str(e):
        # likely wrong endpoint URL — recheck base_url config
        raise ConfigurationError(str(e)) from e
    raise

Prevention

When it happens

Trigger: base_url points at a chat/completions or models endpoint instead of /v1/embeddings; the gateway returns {"object": "list"} or metadata without vectors; empty "data": [] after filtering; the model is not an embedding model so the server returns something else entirely.

Common situations: base_url copy-pasted from an LLM chat config (missing /v1/embeddings suffix); pointing at Ollama's /api/chat; provider changed response schema; requesting a generative model on the embeddings route.

Related errors


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