Skip to content

[FEATURE REQ] Support lazy/async token acquisition in AgentsClientBuilder for reactive applications #47539

@cephalin

Description

@cephalin

Is your feature request related to a problem? Please describe.

When using the Azure AI Agents SDK in Spring WebFlux (reactive) applications, client creation fails with IllegalStateException: channel not registered to an event loop during deployment to Azure App Service.

Root cause: The AgentsClientBuilder.buildConversationsAsyncClient() method calls TokenUtils.getBearerTokenSupplier() which eagerly acquires tokens during .build(). This triggers DefaultAzureCredential to synchronously check multiple credential providers using blocking HTTP calls via Netty. This happens before Netty's event loops are fully initialized in App Service's startup sequence.
Describe the solution you'd like
A clear and concise description of what you want to happen.

Stack trace:

java.lang.IllegalStateException: channel not registered to an event loop
at io.netty.channel.AbstractChannel.eventLoop(AbstractChannel.java:135)
at com.azure.core.http.netty.implementation.NettyUtility.closeConnection(NettyUtility.java:79)
at com.azure.ai.agents.implementation.TokenUtils.lambda$getBearerTokenSupplier$0(TokenUtils.java:39)
at com.openai.credential.BearerTokenCredential.token(BearerTokenCredential.kt:35)
at com.openai.core.ClientOptions$Builder.build(ClientOptions.kt:543)
at com.azure.ai.agents.AgentsClientBuilder.buildConversationsAsyncClient(AgentsClientBuilder.java:331)

Describe the solution you'd like

Make token acquisition lazy - defer authentication until the first API call rather than during client construction:

  1. TokenUtils.getBearerTokenSupplier() should return a supplier that fetches tokens on-demand
  2. Token acquisition should happen asynchronously when making API calls, not during .build()
  3. Use CompletableFuture or reactive types instead of blocking calls

This pattern is common in other Azure SDKs (e.g., OpenAIAsyncClient from azure-ai-openai doesn't authenticate during construction).

Describe alternatives you've considered

Current workaround: Create a singleton factory that initializes clients during application startup (after Netty is ready), then inject the pre-built clients into prototype-scoped beans. This works but adds complexity.

Why this matters: Spring WebFlux and other reactive frameworks are increasingly common for Azure applications. The SDK should work seamlessly in both blocking and non-blocking contexts.

Additional context

  • SDK version: azure-ai-agents:1.0.0-beta.1
  • Service version: AgentsServiceVersion.V2025_11_15_PREVIEW
  • Java version: 21
  • Framework: Spring Boot 3.4.1 with WebFlux
  • Deployment: Azure App Service (Linux, Java 21)
  • Related: The issue occurs specifically during App Service startup timing, but the underlying problem is the synchronous token acquisition during client construction

Metadata

Metadata

Assignees

No one assigned

    Labels

    customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-triageWorkflow: This is a new issue that needs to be triaged to the appropriate team.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions