Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit a0d5470

Browse files
committed
fix: await saveCredentialsForProfile inside .then() callback to prevent race condition
Move saveCredentialsForProfile calls inside the .then() callbacks and make them async/await to ensure credentials are saved as part of the promise chain. This prevents race conditions when multiple concurrent requests share the same refresh promise.
1 parent 2e924c6 commit a0d5470

1 file changed

Lines changed: 10 additions & 10 deletions

File tree

src/integrations/openai-codex/oauth.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -490,24 +490,24 @@ export class OpenAiCodexOAuthManager {
490490
`[openai-codex-oauth] Access token expired for profile ${profileId || "global"} (expires=${credentials.expires}). Refreshing...`,
491491
)
492492
const prevRefreshToken = credentials.refresh_token
493-
refreshPromise = refreshAccessToken(credentials).then((newCreds) => {
493+
refreshPromise = refreshAccessToken(credentials).then(async (newCreds) => {
494494
const rotated = newCreds.refresh_token !== prevRefreshToken
495495
this.log(
496496
`[openai-codex-oauth] Refresh response received for profile ${profileId || "global"} (expires_in≈${Math.round(
497497
(newCreds.expires - Date.now()) / 1000,
498498
)}s, refresh_token_rotated=${rotated})`,
499499
)
500+
await this.saveCredentialsForProfile(newCreds, profileId)
501+
this.log(
502+
`[openai-codex-oauth] Token persisted for profile ${profileId || "global"} (expires=${newCreds.expires})`,
503+
)
500504
return newCreds
501505
})
502506
this.refreshPromises.set(cacheKey, refreshPromise)
503507
}
504508

505509
const newCredentials = await refreshPromise
506510
this.refreshPromises.delete(cacheKey)
507-
await this.saveCredentialsForProfile(newCredentials, profileId)
508-
this.log(
509-
`[openai-codex-oauth] Token persisted for profile ${profileId || "global"} (expires=${newCredentials.expires})`,
510-
)
511511
credentials = newCredentials
512512
} catch (error) {
513513
this.refreshPromises.delete(cacheKey)
@@ -553,24 +553,24 @@ export class OpenAiCodexOAuthManager {
553553
this.log(
554554
`[openai-codex-oauth] Forcing token refresh for profile ${profileId || "global"} (expires=${credentials.expires})...`,
555555
)
556-
refreshPromise = refreshAccessToken(credentials).then((newCreds) => {
556+
refreshPromise = refreshAccessToken(credentials).then(async (newCreds) => {
557557
const rotated = newCreds.refresh_token !== prevRefreshToken
558558
this.log(
559559
`[openai-codex-oauth] Forced refresh response received for profile ${profileId || "global"} (expires_in≈${Math.round(
560560
(newCreds.expires - Date.now()) / 1000,
561561
)}s, refresh_token_rotated=${rotated})`,
562562
)
563+
await this.saveCredentialsForProfile(newCreds, profileId)
564+
this.log(
565+
`[openai-codex-oauth] Forced token persisted for profile ${profileId || "global"} (expires=${newCreds.expires})`,
566+
)
563567
return newCreds
564568
})
565569
this.refreshPromises.set(cacheKey, refreshPromise)
566570
}
567571

568572
const newCredentials = await refreshPromise
569573
this.refreshPromises.delete(cacheKey)
570-
await this.saveCredentialsForProfile(newCredentials, profileId)
571-
this.log(
572-
`[openai-codex-oauth] Forced token persisted for profile ${profileId || "global"} (expires=${newCredentials.expires})`,
573-
)
574574
return newCredentials.access_token
575575
} catch (error) {
576576
this.refreshPromises.delete(cacheKey)

0 commit comments

Comments
 (0)