Repository: All-Hands-AI/OpenHands
File: enterprise/storage/saas_settings_store.py (Python)

Code before:
        )

        if not local_deploy:
            # Get user info to add to litellm
            token_manager = TokenManager()
            keycloak_user_info = (
                await token_manager.get_user_info_from_user_id(self.user_id) or {}
            )

            async with httpx.AsyncClient(
                verify=httpx_verify_option(),
                headers={
                    'x-goog-api-key': LITE_LLM_API_KEY,
                },
            ) as client:
                # Get the previous max budget to prevent accidental loss.
                #
                # LiteLLM API behavior changed between versions:
                # - v1.79.x and earlier: GET /user/info always succeeds, returning
                #   empty user_info for non-existent users
                # - v1.80.x and later: GET /user/info returns 404 for non-existent users
                #
                # We handle both cases to maintain compatibility during the transition:
                # - 200 OK: User exists, extract their info
                # - 404 Not Found: User doesn't exist yet (new user), use empty dict
                # - Other errors: Raise as before (unexpected server issues)
                response = await client.get(
                    f'{LITE_LLM_API_URL}/user/info?user_id={self.user_id}'
                )
                user_info: dict
                if response.status_code == 404:
                    # New user - doesn't exist in LiteLLM yet (v1.80+ behavior)
                    user_info = {}
                else:
                    # For any other status, use standard error handling
                    response.raise_for_status()
                    response_json = response.json()
                    user_info = response_json.get('user_info') or {}
                logger.info(
                    f'creating_litellm_user: {self.user_id}; prev_max_budget: {user_info.get("max_budget")}; prev_metadata: {user_info.get("metadata")}'
                )
                max_budget = user_info.get('max_budget') or DEFAULT_INITIAL_BUDGET
                spend = user_info.get('spend') or 0

                with session_maker() as session:
                    user_settings = self.get_user_settings_by_keycloak_id(
                        self.user_id, session
                    )
                    # In upgrade to V4, we no longer use billing margin, but instead apply this directly
                    # in litellm. The default billing marign was 2 before this (hence the magic numbers below)
                    if (

Review comment (suggestion):
```suggestion
                # LiteLLM v1.80+ returns 404 for non-existent users (previously returned empty user_info)
```

Code after:
        )

        if not local_deploy:
            # Get user info to add to litellm
            token_manager = TokenManager()
            keycloak_user_info = (
                await token_manager.get_user_info_from_user_id(self.user_id) or {}
            )

            async with httpx.AsyncClient(
                verify=httpx_verify_option(),
                headers={
                    'x-goog-api-key': LITE_LLM_API_KEY,
                },
            ) as client:
                # Get the previous max budget to prevent accidental loss.
                #
                # LiteLLM v1.80+ returns 404 for non-existent users (previously returned empty user_info)
                response = await client.get(
                    f'{LITE_LLM_API_URL}/user/info?user_id={self.user_id}'
                )
                user_info: dict
                if response.status_code == 404:
                    # New user - doesn't exist in LiteLLM yet (v1.80+ behavior)
                    user_info = {}
                else:
                    # For any other status, use standard error handling
                    response.raise_for_status()
                    response_json = response.json()
                    user_info = response_json.get('user_info') or {}
                logger.info(
                    f'creating_litellm_user: {self.user_id}; prev_max_budget: {user_info.get("max_budget")}; prev_metadata: {user_info.get("metadata")}'
                )
                max_budget = user_info.get('max_budget') or DEFAULT_INITIAL_BUDGET
                spend = user_info.get('spend') or 0

                with session_maker() as session:
                    user_settings = self.get_user_settings_by_keycloak_id(
                        self.user_id, session
                    )
                    # In upgrade to V4, we no longer use billing margin, but instead apply this directly
                    # in litellm. The default billing marign was 2 before this (hence the magic numbers below)
                    if (
                        user_settings
                        and user_settings.user_version < 4
                        and user_settings.billing_margin
                        and user_settings.billing_margin != 1.0
                    ):
                        billing_margin = user_settings.billing_margin
                        logger.info(
                            'user_settings_v4_budget_upgrade',