{"record":{"id":"06d34a47a4c488f4","repo":"chroma-core/chroma","slug":"request-to-chroma-cloud-api-timed-out-after-60-sec","errorCode":null,"errorMessage":"Request to Chroma Cloud API timed out after 60 seconds","messagePattern":"Request to Chroma Cloud API timed out after 60 seconds","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py","lineNumber":108,"sourceCode":"            \"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:\n            # Handle both dict format and SparseVector format\n            if isinstance(emb, dict):\n                indices = emb.get(\"indices\", [])\n                values = emb.get(\"values\", [])","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/chroma_cloud_splade_embedding_function.py#L90-L126","documentation":"The /embed_sparse request is sent with timeout=60; if httpx raises TimeoutException (connect/read/write/pool timeout) the function converts it to RuntimeError with this fixed message. It signals the API endpoint did not answer in time, not that your inputs were wrong.","triggerScenarios":"Calling ef(texts) with large batches of texts where the server takes more than 60s to return sparse embeddings; slow or saturated networks; Chroma Cloud latency spikes; connection pool starvation from many concurrent EF instances.","commonSituations":"Bulk ingestion jobs embedding thousands of documents per call; running many workers against the same endpoint during load; mobile/high-latency networks; concurrent requests exhausting the shared httpx.Client pool.","solutions":["Retry with exponential backoff — timeouts are frequently transient.","Reduce batch size so each request finishes well under 60s.","Run fewer concurrent embedding calls or share one EF instance across threads instead of many.","If it persists, check network egress and Chroma Cloud status."],"exampleFix":"# before\nvecs = ef(big_batch)  # RuntimeError: timed out after 60 seconds\n\n# after: smaller batches + retry\nimport time\nvecs = []\nfor i in range(0, len(docs), 64):\n    for attempt in range(3):\n        try:\n            vecs += ef(docs[i:i + 64])\n            break\n        except RuntimeError as e:\n            if \"timed out\" not in str(e) or attempt == 2:\n                raise\n            time.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":"# keep batches small enough that a request reliably finishes < 60s\nBATCH = 64\nassert len(batch) <= BATCH","typeGuard":null,"tryCatchPattern":"import time\n\ndef embed_retry(ef, texts, retries=3):\n    for attempt in range(retries + 1):\n        try:\n            return ef(texts)\n        except RuntimeError as e:\n            if \"timed out\" not in str(e) or attempt == retries:\n                raise\n            time.sleep(2 ** attempt)","preventionTips":["Embed in modest batches (e.g. 32-128 texts) instead of one huge call.","Bound concurrency to avoid starving the shared httpx client pool.","Wrap embed calls in retry-with-backoff tuned to the fixed 60s client timeout."],"tags":["chroma-cloud","splade","timeout","retry","sparse-embeddings"],"backgroundTag":"request-timeout","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}