You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix: clear WorkloadIdentityAuth refresh state after synchronous provider failures #852
WorkloadIdentityAuth.getTokenAsync() can permanently poison its token-refresh state when a custom SubjectTokenProvider.getTokenAsync() throws synchronously instead of returning an exceptionally completed future.
The method stores a new CompletableFuture in refreshInFlight before calling refreshTokenAsync(). If the provider throws synchronously, the exception escapes before finishRefresh() is registered, so refreshInFlight is never cleared or completed.
Reproduction
Implement a provider whose asynchronous method throws directly:
assertThrows<IllegalStateException> { auth.getTokenAsync() }
val second = auth.getTokenAsync()
assertTimeoutPreemptively(Duration.ofSeconds(1)) { second.join() }
Code reference
openai-java-core/src/main/kotlin/com/openai/auth/WorkloadIdentityAuth.kt:134-152 stores refreshInFlight before starting a refresh.
WorkloadIdentityAuth.kt:157-174 calls performRefreshAndComplete() or refreshTokenAsync() without catching synchronous exceptions.
WorkloadIdentityAuth.kt:178-182 only clears the state from the asynchronous completion callback.
SubjectTokenProvider.kt:31-38 allows custom implementations of the async provider method.
Expected behavior
A synchronous provider exception should be converted into a failed future, and refreshInFlight should be cleared so later calls can retry or fail normally.
Actual behavior
The first call throws synchronously. Subsequent callers observe the abandoned refreshInFlight future and wait forever.
The same issue can occur on the background refresh path when refreshTokenAsync() throws before registering its completion callback.
Why it matters
A transient or poorly behaved custom credential provider can permanently hang all future asynchronous authentication attempts in a long-lived client. This is especially problematic because the failure is not limited to the request that encountered the provider exception.
Activity
[-]test placeholder[/-][+]fix: clear WorkloadIdentityAuth refresh state after synchronous provider failures[/+]