BerriAI/litellm · error · Exception

LiteLLM Managed {self.resource_type} with id={unified_resour

Error message

LiteLLM Managed {self.resource_type} with id={unified_resource_id} not found

What it means

Raised by BaseManagedResource.delete_resource (and similar managed-resource flows) when no row with the given unified_resource_id exists in the database before deletion. LiteLLM Managed resources (unified IDs across models) first read the current value; a missing row means the ID is wrong, already deleted, or scoped to another organization.

Source

Thrown at litellm/llms/base_llm/managed_resources/base_managed_resource.py:270

        unified_resource_id: str,
        litellm_parent_otel_span: Span | None = None,
    ) -> ResourceObjectType | None:
        """
        Delete unified resource from cache and database.

        Args:
            unified_resource_id: The unified resource ID to delete
            litellm_parent_otel_span: OpenTelemetry span for tracing

        Returns:
            The deleted resource object or None if not found
        """
        # Get old value from database
        table: Final = getattr(self.prisma_client.db, self.table_name)
        initial_value: Final = await table.find_first(where={"unified_resource_id": unified_resource_id})

        if initial_value is None:
            raise Exception(f"LiteLLM Managed {self.resource_type} with id={unified_resource_id} not found")

        # Delete from cache
        await self.internal_usage_cache.async_set_cache(
            key=unified_resource_id,
            value=None,
            litellm_parent_otel_span=litellm_parent_otel_span,
        )

        # Delete from database
        await table.delete(where={"unified_resource_id": unified_resource_id})

        return initial_value.resource_object

    async def can_user_access_unified_resource_id(
        self,
        unified_resource_id: str,
        user_api_key_dict: UserAPIKeyAuth,
        litellm_parent_otel_span: Span | None = None,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Re-list resources to get current unified_resource_ids and retry the delete with a fresh ID.
  2. Make client deletes idempotent: treat 'not found' as success (catch and check the message).
  3. Verify org/user scoping — the ID may exist but be invisible to the requesting tenant.
  4. Check for concurrent deletions (audit log) before assuming data loss.

Example fix

# before
await managed_resource.delete_resource(unified_resource_id=rid)  # raises on stale ID

# after
try:
    await managed_resource.delete_resource(unified_resource_id=rid)
except Exception as e:
    if 'not found' in str(e):
        return  # already deleted; treat as success
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

async def resource_exists(handler, unified_resource_id: str) -> bool:
    return await handler.get_resource(unified_resource_id=unified_resource_id) is not None

Try / catch

try:
    await handler.delete_resource(unified_resource_id=rid)
except Exception as e:
    if 'not found' in str(e):
        return {'deleted': False, 'reason': 'already-gone'}  # idempotent success
    raise

Prevention

When it happens

Trigger: DELETE on a managed resource endpoint with an expired/incorrect unified_resource_id; double-submit of the same delete request (second one finds nothing); resource created under a different org/user and deleted under another; stale ID cached in the client.

Common situations: Idempotent-delete assumptions: clients retrying deletes after timeout; UI holding stale IDs after another admin removed the resource; test runs against the wrong database instance.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/1481003b201524e5. Report an issue: GitHub.