{"record":{"id":"5ccac4442ec70c44","repo":"HKUDS/DeepTutor","slug":"embedding-provider-returned-error-payload-err","errorCode":null,"errorMessage":"Embedding provider returned error payload: {err}","messagePattern":"Embedding provider returned error payload: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/embedding/adapters/openai_compatible.py","lineNumber":99,"sourceCode":"            raise ValueError(f\"Embedding response is not a JSON object: type={type(data).__name__}\")\n\n        # Some providers return HTTP 200 with {\"error\": ...} payload.\n        if \"error\" in data:\n            err = data.get(\"error\")\n            if isinstance(err, dict):\n                msg = (\n                    err.get(\"message\")\n                    or err.get(\"msg\")\n                    or err.get(\"detail\")\n                    or json.dumps(err, ensure_ascii=False)\n                )\n                code = err.get(\"code\")\n                etype = err.get(\"type\")\n                raise ValueError(\n                    f\"Embedding provider returned error payload: \"\n                    f\"message={msg}, code={code}, type={etype}\"\n                )\n            raise ValueError(f\"Embedding provider returned error payload: {err}\")\n\n        candidates = []\n        # Standard OpenAI schema\n        if isinstance(data.get(\"data\"), list):\n            candidates.append(data[\"data\"])\n        # Common proxy schema\n        if isinstance(data.get(\"embeddings\"), list):\n            candidates.append(data[\"embeddings\"])\n        # Ollama /api/embeddings returns singular \"embedding\" as a flat vector\n        if isinstance(data.get(\"embedding\"), list):\n            emb = data[\"embedding\"]\n            if emb and isinstance(emb[0], (int, float)):\n                candidates.append([emb])\n            else:\n                candidates.append(emb)\n        # Nested result/output variants\n        result = data.get(\"result\")\n        if isinstance(result, dict):","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/embedding/adapters/openai_compatible.py#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmodel = \"text-embeddings-3-small\"  # typo, gateway returns {\"error\": {...}}\n// after\nmodel = \"text-embedding-3-small\"","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try:\n    resp = await adapter.embed(req)\nexcept ValueError as e:\n    if \"error payload\" in str(e):\n        # provider-side error surfaced in a 200 body; log and surface to user / alert\n        log_provider_error(e)\n    raise","preventionTips":["Log the full message= field — it is the provider's own diagnostic","Health-check gateway configs (model id, key) before long indexing runs"],"tags":["embeddings","openai-compatible","provider-error","http-200-with-error"],"backgroundTag":"api-error-payload-in-200-response","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}