HKUDS/DeepTutor · error · ValueError
Embedding provider returned error payload: {err}
Error message
Embedding provider returned error payload: {err} What it means
The HTTP request itself succeeded (often HTTP 200), but the JSON body contains a top-level "error" object instead of embedding vectors. Many OpenAI-compatible gateways report auth failures, invalid model names, or quota exhaustion this way instead of using an HTTP error status, so the adapter checks for it after parsing.
Source
Thrown at deeptutor/services/embedding/adapters/openai_compatible.py:99
raise ValueError(f"Embedding response is not a JSON object: type={type(data).__name__}")
# Some providers return HTTP 200 with {"error": ...} payload.
if "error" in data:
err = data.get("error")
if isinstance(err, dict):
msg = (
err.get("message")
or err.get("msg")
or err.get("detail")
or json.dumps(err, ensure_ascii=False)
)
code = err.get("code")
etype = err.get("type")
raise ValueError(
f"Embedding provider returned error payload: "
f"message={msg}, code={code}, type={etype}"
)
raise ValueError(f"Embedding provider returned error payload: {err}")
candidates = []
# Standard OpenAI schema
if isinstance(data.get("data"), list):
candidates.append(data["data"])
# Common proxy schema
if isinstance(data.get("embeddings"), list):
candidates.append(data["embeddings"])
# Ollama /api/embeddings returns singular "embedding" as a flat vector
if isinstance(data.get("embedding"), list):
emb = data["embedding"]
if emb and isinstance(emb[0], (int, float)):
candidates.append([emb])
else:
candidates.append(emb)
# Nested result/output variants
result = data.get("result")
if isinstance(result, dict):View on GitHub (pinned to 3e82f13042)
Solutions
- Read the embedded message= in the ValueError — it is the provider's own diagnostic (model name, auth, quota)
- Fix the model id in the embedding binding to one the gateway actually serves
- Verify the API key is valid and has embedding quota; test with curl against the same base_url
- If the gateway consistently returns 200-with-error, ask it to return proper HTTP status codes or switch to one that does
Example fix
// before
model = "text-embeddings-3-small" # typo, gateway returns {"error": {...}}
// after
model = "text-embedding-3-small" Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try:
resp = await adapter.embed(req)
except ValueError as e:
if "error payload" in str(e):
# provider-side error surfaced in a 200 body; log and surface to user / alert
log_provider_error(e)
raise Prevention
- Log the full message= field — it is the provider's own diagnostic
- Health-check gateway configs (model id, key) before long indexing runs
When it happens
Trigger: POST to base_url embeddings endpoint returns 200/4xx with body like {"error": {"message": "model not found", "code": ..., "type": ...}} — e.g. wrong model name on a proxy, expired API key, or exhausted quota on a gateway that wraps errors in a 200.
Common situations: Typo'd model id on LiteLLM/Ollama/OpenRouter-style proxies; key rotated/revoked; free-tier quota exhausted; gateway downgraded the error into a 200 response.
Related errors
- Embedding provider returned HTTP {response.status_code}
- Failed to reload channels: {type(exc).__name__}
- Cohere v1 API does not support multimodal `contents`. Use em
- Cohere model '{model_name}' does not support multimodal `con
- Cohere v2 does not support content type '{kind}'
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/5ccac4442ec70c44.
Report an issue: GitHub.