{"record":{"id":"7de2f7e639525998","repo":"BerriAI/litellm","slug":"not-connected-to-db-7de2f7","errorCode":null,"errorMessage":"Not connected to DB!","messagePattern":"Not connected to DB!","errorType":"exception","errorClass":"Exception","httpStatus":500,"severity":"error","filePath":"litellm/proxy/management_endpoints/customer_endpoints.py","lineNumber":624,"sourceCode":"    --data '{\n        \"user_id\": \"user_1\",\n        \"object_permission\": {\n          \"mcp_servers\": [\"server_3\"],\n          \"vector_stores\": [\"vector_store_2\", \"vector_store_3\"]\n        }\n      }'\n\n    See below for all params\n    ```\n    \"\"\"\n\n    from litellm.proxy.proxy_server import litellm_proxy_admin_name, prisma_client\n\n    try:\n        data_json: Final = _STR_OBJECT_DICT.validate_python(data.json())\n        # get the row from db\n        if prisma_client is None:\n            raise Exception(\"Not connected to DB!\")\n\n        # get non default values for key\n        non_default_values: Final = dict[str, object]()\n        for k, v in data_json.items():\n            if v is not None and v not in (\n                [],\n                {},\n                0,\n            ):  # models default to [], spend defaults to 0, we should not reset these values\n                non_default_values[k] = v\n\n        ## Get end user table data ##\n        end_user_table_data: Final = await _typed_table(EndUserRepository(prisma_client)).find_first(\n            where={\"user_id\": data.user_id}, include={\"litellm_budget_table\": True}\n        )\n\n        if end_user_table_data is None:\n            raise ProxyException(","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/customer_endpoints.py#L606-L642","documentation":"POST /customer/update raises a bare Exception('Not connected to DB!') when prisma_client is None; the surrounding handler passes it through handle_exception_on_proxy, which surfaces it to the caller as an HTTP 500. Same root cause as the standardized db_not_connected_error used elsewhere, but via a plain exception on this route.","triggerScenarios":"POST /customer/update with any payload on a proxy started without DATABASE_URL or whose Prisma connection never came up.","commonSituations":"Attempting customer updates on routing-only deployments; DATABASE_URL unset in one environment (staging) while tooling assumes parity with another (prod); DB outages after boot.","solutions":["Set DATABASE_URL to a postgresql:// connection string and restart the proxy","Verify Prisma connectivity in startup logs and via another DB-backed endpoint","Retry the update once the DB-backed health check passes","Skip update calls on deployments intentionally running without a database"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\n\n\ndef update_endpoint_ready() -> bool:\n    return os.getenv(\"DATABASE_URL\", \"\").startswith((\"postgresql://\", \"postgres://\"))","typeGuard":null,"tryCatchPattern":"try:\n    r = httpx.post(f\"{base}/customer/update\", json=payload, headers=headers)\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 500 and \"Not connected to DB\" in e.response.text:\n        raise RuntimeError(\"proxy has no DATABASE_URL; /customer/update needs Postgres\") from e\n    raise","preventionTips":["Never assume management endpoints work without a configured database","Include DATABASE_URL in infrastructure-as-code templates so no environment boots without it","Wrap customer-update automation with a DB readiness precondition"],"tags":["litellm","database-connection","postgres","customer-management","http-500"],"backgroundTag":"database-not-connected","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}