{"record":{"id":"1228b3bc6e7bdfad","repo":"BerriAI/litellm","slug":"db-not-connected-this-endpoint-needs-a-database-1228b3","errorCode":null,"errorMessage":"DB not connected. This endpoint needs a database; set DATABASE_URL to a PostgreSQL connection string (postgresql://...) to enable it. See https://docs.litellm.ai/docs/proxy/virtual_keys","messagePattern":"DB not connected\\. This endpoint needs a database; set DATABASE_URL to a PostgreSQL connection string \\(postgresql://\\.\\.\\.\\) to enable it\\. See https://docs\\.litellm\\.ai/docs/proxy/virtual_keys","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"litellm/proxy/management_endpoints/common_daily_activity.py","lineNumber":1004,"sourceCode":"    page: int,\n    page_size: int,\n    exclude_entity_ids: list[str] | None = None,\n    metadata_metrics_func: Callable[[Sequence[DailySpendRecord]], SpendMetrics] | None = None,\n    timezone_offset_minutes: int | None = None,\n    include_current_utc_day: bool = False,\n    resolve_entity_metadata: Callable[[Sequence[DailySpendRecord]], Awaitable[dict[str, dict[str, object]]]]\n    | None = None,\n) -> SpendAnalyticsPaginatedResponse:\n    \"\"\"Common function to get daily activity for any entity type.\n\n    ``resolve_entity_metadata`` lets a caller resolve entity metadata from the\n    rows actually on the page (e.g. user_id -> user_email) instead of fetching\n    the whole entity table upfront, which matters when the entity set is\n    unbounded.\n    \"\"\"\n\n    if prisma_client is None:\n        raise HTTPException(\n            status_code=500,\n            detail={\"error\": CommonProxyErrors.db_not_connected_error.value},\n        )\n\n    if start_date is None or end_date is None:\n        raise HTTPException(\n            status_code=status.HTTP_400_BAD_REQUEST,\n            detail={\"error\": \"Please provide start_date and end_date\"},\n        )\n\n    try:\n        where_conditions: Final = _build_where_conditions(\n            entity_id_field=entity_id_field,\n            entity_id=entity_id,\n            start_date=start_date,\n            end_date=end_date,\n            model=model,\n            api_key=api_key,","sourceCodeStart":986,"sourceCodeEnd":1022,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/common_daily_activity.py#L986-L1022","documentation":"get_daily_activity is the shared paginated spend-analytics core behind the daily-activity endpoints (/global, per-user, per-team, per-tag variants). It queries the daily-spend tables through raw SQL on Prisma, so it first asserts prisma_client is not None and raises HTTP 500 with CommonProxyErrors.db_not_connected_error when the proxy has no database. Spend analytics are entirely DB-backed — there is no in-memory fallback.","triggerScenarios":"Calling any daily-activity/spend-report endpoint (e.g. GET /global/spend/report or the per-entity daily activity routes that delegate here) on a proxy without DATABASE_URL configured.","commonSituations":"Pointing spend dashboards at a config-only proxy; DB env var missing in one of several proxy replicas behind a load balancer; analytics enabled in the UI before Postgres was provisioned.","solutions":["Set DATABASE_URL=\"postgresql://...\" and restart the proxy","Confirm spend tables exist by letting Prisma run migrations on startup (automatic when the DB is reachable)","Retry the analytics call with both start_date and end_date supplied once a 200 returns from GET /budget/list as a DB sanity check"],"exampleFix":"# before\nlitellm --config config.yaml  # no DATABASE_URL\ncurl http://localhost:4000/global/spend/report -H \"Authorization: Bearer $KEY\"  # 500 DB not connected\n\n# after\nexport DATABASE_URL=\"postgresql://user:pass@db:5432/litellm\" && litellm --config config.yaml\ncurl \"http://localhost:4000/global/spend/report?start_date=2026-08-01&end_date=2026-08-18\" -H \"Authorization: Bearer $KEY\"","handlingStrategy":"validation","validationCode":"import os\n\n# All spend-analytics endpoints are DB-backed; check the deployment first\nif not os.getenv(\"DATABASE_URL\", \"\").startswith(\"postgresql://\"):\n    raise SystemExit(\"proxy has no DB; daily-activity endpoints return 500\")","typeGuard":null,"tryCatchPattern":"import httpx\n\ntry:\n    r = httpx.get(f\"{PROXY_URL}/global/spend/report\",\n                  params={\"start_date\": \"2026-08-01\", \"end_date\": \"2026-08-18\"},\n                  headers=hdrs)\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 500 and \"DB not connected\" in e.response.text:\n        raise RuntimeError(\"configure DATABASE_URL before querying spend analytics\") from e\n    raise","preventionTips":["Provision Postgres before shipping spend dashboards","Ensure every proxy replica behind a LB has DATABASE_URL set"],"tags":["litellm-proxy","database","postgres","spend-analytics","configuration"],"backgroundTag":"database-not-connected","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}