{"record":{"id":"d994889a62dee14d","repo":"chroma-core/chroma","slug":"could-not-connect-to-tenant-tenant-are-you-sure","errorCode":null,"errorMessage":"Could not connect to tenant {tenant}. Are you sure it exists?","messagePattern":"Could not connect to tenant (.+?)\\. Are you sure it exists\\?","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/async_client.py","lineNumber":154,"sourceCode":"        self.database = database\n\n    @override\n    async def set_database(self, database: str) -> None:\n        await self._validate_tenant_database(tenant=self.tenant, database=database)\n        self.database = database\n\n    async def _validate_tenant_database(self, tenant: str, database: str) -> None:\n        try:\n            await self._admin_client.get_tenant(name=tenant)\n        except httpx.ConnectError:\n            raise ValueError(\n                \"Could not connect to a Chroma server. Are you sure it is running?\"\n            )\n        # Propagate ChromaErrors\n        except ChromaError as e:\n            raise e\n        except Exception:\n            raise ValueError(\n                f\"Could not connect to tenant {tenant}. Are you sure it exists?\"\n            )\n\n        try:\n            await self._admin_client.get_database(name=database, tenant=tenant)\n        except httpx.ConnectError:\n            raise ValueError(\n                \"Could not connect to a Chroma server. Are you sure it is running?\"\n            )\n\n    # region BaseAPI Methods\n    # Note - we could do this in less verbose ways, but they break type checking\n    @override\n    async def heartbeat(self) -> int:\n        return await self._server.heartbeat()\n\n    @override\n    async def list_collections(","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/async_client.py#L136-L172","documentation":"Catch-all branch in the async client's tenant validation: get_tenant() raised something that is neither httpx.ConnectError nor a ChromaError. Note that a genuinely missing tenant does NOT produce this error — the server returns a structured 404 that the HTTP client maps to a ChromaError, which is re-raised verbatim by the `except ChromaError` branch above. So this misleading \"Are you sure it exists?\" ValueError almost always masks a different, unexpected failure (a proxy response that is not a Chroma error envelope, a protocol error, a buggy auth provider).","triggerScenarios":"A reverse proxy/LB in front of Chroma returns a non-Chroma error (502/504 HTML or plain-text body), which _raise_chroma_error converts to a bare Exception; a very old Chroma server that does not return structured error JSON; a custom auth provider or transport raising a non-Chroma exception; httpx.RemoteProtocolError from a truncated response.","commonSituations":"nginx/traefik returning 502 while the Chroma container restarts; API-gateway rate limiting with a non-Chroma response body; mixed client/server versions where the error envelope differs; debugging in the wrong direction because the message mentions tenants.","solutions":["Inspect the chained cause — catch ValueError and print e.__cause__ (or the full traceback) to see the real underlying exception and response body.","Test the server directly, bypassing any proxy: curl http://<host>:8000/api/v2/v2/tenant/<name> style admin endpoints or at least /api/v2/heartbeat.","Align client and server chromadb versions so error envelopes match.","If a proxy is in the path, check its logs and make sure it forwards Chroma's JSON error bodies unchanged.","Only then verify the tenant actually exists via an admin API call."],"exampleFix":"# before\ntry:\n    client = await AsyncClient.create(tenant=\"acme\")\nexcept ValueError as e:\n    print(e)  # 'Could not connect to tenant acme...' -- misleading\n\n# after\nexcept ValueError as e:\n    print(\"real cause:\", repr(e.__cause__))  # e.g. Exception('502 Bad Gateway') from proxy","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from chromadb.errors import ChromaError\n\ntry:\n    client = await AsyncClient.create(tenant=\"acme\")\nexcept ValueError as e:\n    cause = e.__cause__\n    if isinstance(cause, ChromaError):\n        raise cause  # real Chroma error (e.g. tenant truly missing)\n    # otherwise an unexpected/proxy error hides behind the message\n    raise RuntimeError(f\"tenant validation failed unexpectedly: {cause!r}\") from e","preventionTips":["Always log e.__cause__ when this ValueError appears — the message itself is misleading.","Test tenants through the admin API directly when proxies are in the path.","Keep client and server chromadb versions aligned so error envelopes parse."],"tags":["chroma","tenant","error-mapping","proxy","async"],"backgroundTag":"unexpected-server-response","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}