chroma-core/chroma · error · Exception
{resp.text} (trace ID: {trace_id})
Error message
{resp.text} (trace ID: {trace_id}) What it means
Final fallback in _raise_chroma_error: the response had an error status, but its body did not map to any registered ChromaError type, so the client raises a bare Exception carrying the raw response text (plus the chroma-trace-id header when present). Because this is a plain Exception and not a ChromaError, `except ChromaError` handlers will not catch it.
Source
Thrown at chromadb/api/base_http_client.py:154
"Chroma error response missing required 'message' field: "
f"{resp.text}"
)
trace_id = resp.headers.get("chroma-trace-id")
if trace_id:
message = f"{message} (trace ID: {trace_id})"
raise ValueError(message) from e
except BaseException:
pass
if chroma_error:
raise chroma_error
try:
resp.raise_for_status()
except httpx.HTTPStatusError:
trace_id = resp.headers.get("chroma-trace-id")
if trace_id:
raise Exception(f"{resp.text} (trace ID: {trace_id})")
raise (Exception(resp.text))
def get_request_headers(self) -> Mapping[str, str]:
"""Return headers used for HTTP requests."""
return {}
def get_api_url(self) -> str:
"""Return the API URL for this client."""
return ""
View on GitHub (pinned to aecdd12c8a)
Solutions
- Read the exception message — it contains the raw response body, which identifies the origin (nginx error page, gateway JSON, etc.).
- If it is proxy-generated, fix the proxy config or the backend availability it complains about.
- Confirm the URL actually points at Chroma: curl http://<host>:<port>/api/v2/heartbeat.
- In code behind a proxy, catch plain Exception after ChromaError in your handler chain.
Example fix
# before
try:
col = client.get_collection("docs")
except ChromaError:
... # misses bare Exception from proxy responses
# after
try:
col = client.get_collection("docs")
except ChromaError:
...
except Exception as e: # non-Chroma HTTP failure (proxy 502, 422, ...)
logger.error("raw server/proxy response: %s", e) Defensive patterns
Strategy: try-catch
Validate before calling
import httpx
def points_at_chroma(host: str, port: int) -> bool:
try:
return httpx.get(f"http://{host}:{port}/api/v2/heartbeat", timeout=2).status_code == 200
except httpx.HTTPError:
return False Try / catch
from chromadb.errors import ChromaError
try:
result = collection.query(query_texts=["x"])
except ChromaError:
raise # structured Chroma error
except Exception as e: # bare Exception(resp.text) from non-Chroma responses
logger.error("non-Chroma HTTP error: %s", e)
raise Prevention
- Always include a plain-Exception handler after ChromaError when a proxy is in the path.
- Log the raw body embedded in the message — it identifies which hop produced the error.
- Set proxy read timeouts generously for large query/upsert payloads.
When it happens
Trigger: A reverse proxy returning 502/504 HTML pages when Chroma is down or slow; an API gateway's rate-limit response; FastAPI 422 validation responses ({"detail": [...]}) from hitting a route with bad parameters; connecting to a non-Chroma service on the same port.
Common situations: Chroma behind nginx/traefik/ALB where infrastructure errors surface as raw HTML/text; gateway timeouts on large queries; wrong service targeted in a shared cluster.
Related errors
- Chroma error response missing required 'message' field: {res
- Could not connect to tenant {tenant}. Are you sure it exists
- Could not connect to tenant {tenant}. Are you sure it exists
- Unprocessable Entity: ${response.statusText}
- Unknown error
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/d6887eea40d099df.
Report an issue: GitHub.