{"record":{"id":"a3ef3f700b67e20e","repo":"chroma-core/chroma","slug":"failed-to-get-embeddings-from-chroma-cloud-api-ht","errorCode":null,"errorMessage":"Failed to get embeddings from Chroma Cloud API: HTTP {e.response.status_code} - {e.response.text}","messagePattern":"Failed to get embeddings from Chroma Cloud API: HTTP (.+?) - (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py","lineNumber":104,"sourceCode":"        if not input:\n            return []\n\n        payload: Dict[str, Union[str, Documents]] = {\n            \"texts\": list(input),\n            \"task\": \"\",\n            \"target\": \"\",\n            \"fetch_tokens\": \"true\" if self.include_tokens is True else \"false\",\n        }\n\n        try:\n            import httpx\n\n            response = self._session.post(self._api_url, json=payload, timeout=60)\n            response.raise_for_status()\n            json_response = response.json()\n            return self._parse_response(json_response)\n        except httpx.HTTPStatusError as e:\n            raise RuntimeError(\n                f\"Failed to get embeddings from Chroma Cloud API: HTTP {e.response.status_code} - {e.response.text}\"\n            )\n        except httpx.TimeoutException:\n            raise RuntimeError(\"Request to Chroma Cloud API timed out after 60 seconds\")\n        except httpx.HTTPError as e:\n            raise RuntimeError(f\"Failed to get embeddings from Chroma Cloud API: {e}\")\n        except Exception as e:\n            raise RuntimeError(f\"Unexpected error calling Chroma Cloud API: {e}\")\n\n    def _parse_response(self, response: Any) -> SparseVectors:\n        \"\"\"\n        Parse the response from the Chroma Cloud Sparse Embedding API.\n        \"\"\"\n        raw_embeddings = response[\"embeddings\"]\n\n        # Normalize each sparse vector (sort indices and validate)\n        normalized_vectors: SparseVectors = []\n        for emb in raw_embeddings:","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py#L86-L122","documentation":"In __call__, the POST to the /embed_sparse endpoint is wrapped in try/except; when httpx reports raise_for_status() failed (HTTPStatusError) the function raises RuntimeError embedding the status code and response body. This is the path for any 4xx/5xx reply from the Chroma Cloud sparse embedding API, so the server's own error text travels with the exception.","triggerScenarios":"Calling ef(texts) and the API returns an error status: 401/403 for a bad or expired x-chroma-token, 400 for malformed payload or unsupported model header, 429 for rate limiting, 5xx for server-side failures.","commonSituations":"Expired or revoked API key in a long-running service; rate limits hit during bulk ingestion; Chroma Cloud incidents returning 502/503; a model header value the backend no longer accepts.","solutions":["Parse the status from the message: 401/403 -> refresh CHROMA_API_KEY and restart; 429 -> slow down or batch smaller; 5xx -> retry with backoff later.","Verify the token and model by reproducing the request (the headers are x-chroma-token and x-chroma-embedding-model) with curl.","Add exponential backoff for 429/5xx and treat 4xx as non-retryable.","Check Chroma Cloud status pages if 5xx persists."],"exampleFix":"# before\nvecs = ef([\"hello\"])  # RuntimeError: ... HTTP 429 - rate limited\n\n# after\nimport time\nfor attempt in range(5):\n    try:\n        vecs = ef([\"hello\"])\n        break\n    except RuntimeError as e:\n        if \"HTTP 4\" in str(e) or attempt == 4:\n            raise  # client errors: fix credentials/payload, don't retry\n        time.sleep(2 ** attempt)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import time\n\ndef embed_with_handling(ef, texts, max_retries=5):\n    for attempt in range(max_retries + 1):\n        try:\n            return ef(texts)\n        except RuntimeError as e:\n            msg = str(e)\n            if \"HTTP 401\" in msg or \"HTTP 403\" in msg:\n                raise PermissionError(msg) from e          # fix credentials, no retry\n            if \"HTTP 4\" in msg:\n                raise ValueError(msg) from e               # bad request, no retry\n            if attempt == max_retries:\n                raise\n            time.sleep(min(2 ** attempt, 30))             # 429/5xx: back off and retry","preventionTips":["Add exponential backoff with jitter for 429/5xx around every cloud embed call.","Treat 401/403 as fatal credential events and alert on them.","Batch ingestion adaptively: shrink batch size after 429s."],"tags":["chroma-cloud","splade","http-status-error","api-error","sparse-embeddings"],"backgroundTag":"http-error-response","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}