BerriAI/litellm · error · OrganizationNotFoundError
Organization doesn't exist in db. Organization={org_id}. Cre
Error message
Organization doesn't exist in db. Organization={org_id}. Create organization via `/organization/new` call. What it means
OrganizationNotFoundError raised when the by-id organization query returns None: the row is confirmed absent from LiteLLM_OrganizationTable. Unlike the generic 500 wrapper, this exception deliberately distinguishes 'org really does not exist' from operational failures (which now propagate raw), so callers can treat absence as 'no org restriction' without swallowing DB outages. It subclasses Exception, so existing except Exception handlers keep working.
Source
Thrown at litellm/proxy/auth/auth_checks.py:3324
if deserialized_org is not None:
return deserialized_org
# else, check db
try:
query_kwargs: Final[dict[str, Mapping[str, object]]] = {"where": {"organization_id": org_id}}
if include_budget_table:
query_kwargs["include"] = {"litellm_budget_table": True}
response: Final = await _model_dump_table(OrganizationRepository(prisma_client)).find_unique(**query_kwargs)
except Exception:
# An operational failure (DB down, timeout, cache fault) is NOT the same fact as a confirmed
# missing row, and relabelling it as "doesn't exist" made every caller unable to tell them
# apart — a caller that treats absence as "this org places no restriction" then drops a real
# org ceiling during an outage. Propagate the real error; callers that already catch
# Exception are unaffected.
raise
if response is None:
raise OrganizationNotFoundError(
f"Organization doesn't exist in db. Organization={org_id}. Create organization via `/organization/new` call."
)
_org_obj: Final = LiteLLM_OrganizationTable.model_validate(response.model_dump())
# Cache the result
await user_api_key_cache.async_set_cache(
key=cache_key,
value=_org_obj,
model_type=LiteLLM_OrganizationTable,
ttl=DEFAULT_IN_MEMORY_TTL,
)
return _org_obj
async def _get_resources_from_access_groups(
access_group_ids: Sequence[str],
resource_field: Literal["access_model_names", "access_mcp_server_ids", "access_agent_ids"],View on GitHub (pinned to 77b7c6c40c)
Solutions
- Create the organization via POST /organization/new and use the returned organization_id on keys/users
- GET /organization/list to confirm the correct organization_id; update the key or user via /key/update or /user/update to point at an existing org
- When deleting organizations, also detach or update keys/users/teams that reference the org id
Example fix
curl -X POST http://localhost:4000/organization/new \
-H "Authorization: Bearer $MASTER_KEY" \
-d '{"organization_alias": "acme-corp"}'
# attach key to org
curl -X POST http://localhost:4000/key/update \
-H "Authorization: Bearer $MASTER_KEY" \
-d '{"key": "sk-...", "organization_id": "org-returned-id"}' Defensive patterns
Strategy: type-guard
Validate before calling
orgs = (await client.get("/organization/list")).json()
valid_ids = {o["organization_id"] for o in orgs}
assert key_org_id in valid_ids, f"organization {key_org_id} no longer exists" Type guard
from litellm.proxy.auth.auth_checks import OrganizationNotFoundError
def is_confirmed_missing(exc: Exception) -> bool:
"""True only for a confirmed-absent org, never for an outage."""
return isinstance(exc, OrganizationNotFoundError) Try / catch
from litellm.proxy.auth.auth_checks import OrganizationNotFoundError
try:
org = await get_org_object(org_id, prisma_client, cache)
except OrganizationNotFoundError:
org = None # confirmed absent: treat as 'no org restriction' safely
except Exception:
raise # operational failure: do NOT treat as absence Prevention
- Catch OrganizationNotFoundError specifically instead of bare Exception so DB outages are not mistaken for missing orgs
- Cascade org deletion: detach keys/users/teams when deleting an organization
When it happens
Trigger: A key/user/team references organization_id that has no row — e.g. the org was deleted after keys were issued, the id is a stale JWT claim, or a key was created with a mistyped organization_id.
Common situations: Org deletion without cleaning up member keys/users; environment mismatch (org exists in prod DB, request hits staging); copying key definitions between configs with hardcoded org ids.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- LiteLLM Managed File object with id={file_id} not found
- 404
- Cloudflare Exception - {original_exception.message}
- CohereException - {original_exception.message}
- OpenRouter API key is required. Set OPENROUTER_API_KEY envir
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/163cd77cb87dbcd6.
Report an issue: GitHub.