Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:OpenHands OpenHands OrgService Persist With Compensation

From Leeroopedia
Knowledge Sources
Domains Organization_Management, Multi_Tenancy
Last Updated 2026-02-11 21:00 GMT

Overview

Concrete tool for persisting organization and membership entities with compensating cleanup of LiteLLM resources on failure provided by the OpenHands enterprise storage layer.

Description

OrgService._persist_with_compensation attempts to add the Org and OrgMember entities to the database session and commit the transaction. If the commit fails for any reason (constraint violation, connection error, etc.), the method:

  1. Rolls back the database transaction.
  2. Invokes _cleanup_litellm_resources (at L363-397) to delete the previously provisioned LiteLLM team and API key associated with the organization.
  3. Re-raises the original exception so the caller can handle the failure appropriately.

The _cleanup_litellm_resources method is a best-effort compensating action. It attempts to remove the LiteLLM team and revoke the API key via the LiteLLM proxy API. If the cleanup itself encounters an error, it returns the exception (rather than raising it) so that the original failure is not masked.

This method is private (prefixed with underscore) because it is an internal pipeline step, not intended to be called directly by external consumers.

Usage

This method is called as the final step of the organization creation pipeline, after entity construction and ownership establishment. It should only be invoked when both the Org and OrgMember entities are fully initialized and LiteLLM resources have been provisioned.

Code Reference

Source Location

  • Repository: OpenHands
  • File: enterprise/storage/org_service.py
  • Lines: L282-320 (_persist_with_compensation), L363-397 (_cleanup_litellm_resources)

Signature

async def _persist_with_compensation(
    self,
    org: Org,
    org_member: OrgMember,
    org_id: UUID,
    user_id: str,
) -> Org:
    """Persist org and member entities, cleaning up LiteLLM on failure.

    Args:
        org: The fully constructed Org entity.
        org_member: The fully constructed OrgMember entity.
        org_id: The organization UUID (for LiteLLM cleanup on failure).
        user_id: The user ID (for LiteLLM cleanup on failure).

    Returns:
        The persisted Org entity on success.

    Raises:
        Exception: Re-raises the original database error after compensation.
    """
async def _cleanup_litellm_resources(
    self,
    org_id: UUID,
    user_id: str,
) -> Exception | None:
    """Best-effort cleanup of provisioned LiteLLM team and API key.

    Args:
        org_id: The organization UUID whose LiteLLM team should be deleted.
        user_id: The user ID whose LiteLLM key should be revoked.

    Returns:
        None on successful cleanup, or the Exception encountered during cleanup.
    """

Import

from enterprise.storage.org_service import OrgService

I/O Contract

Inputs

Name Type Required Description
org Org Yes The fully constructed organization entity to persist
org_member OrgMember Yes The fully constructed membership entity to persist
org_id UUID Yes The organization UUID, used for LiteLLM cleanup on failure
user_id str Yes The user ID, used for LiteLLM key cleanup on failure

Outputs

Name Type Description
org Org The persisted Org entity (with database-assigned fields populated) on success

Usage Examples

Basic Usage

from enterprise.storage.org_service import OrgService

org_service = OrgService(session=db_session)

# After entity construction and LiteLLM provisioning...
try:
    persisted_org = await org_service._persist_with_compensation(
        org=org,
        org_member=org_member,
        org_id=org_id,
        user_id=user_id,
    )
    # Success — org and org_member are now in the database
except Exception as e:
    # Database commit failed; LiteLLM resources have been cleaned up
    logger.error(f"Organization creation failed: {e}")
    raise

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment