@@ -117,6 +117,7 @@ import {
117117 createTimestampedBackupPath ,
118118 loadFlaggedAccounts ,
119119 saveFlaggedAccounts ,
120+ withFlaggedAccountStorageTransaction ,
120121 clearFlaggedAccounts ,
121122 StorageError ,
122123 formatStorageErrorHint ,
@@ -189,9 +190,16 @@ function getWorkspaceIdentityKey(account: {
189190 accountId ?: string ;
190191 refreshToken : string ;
191192} ) : string {
192- if ( account . organizationId ) return `organizationId:${ account . organizationId } ` ;
193- if ( account . accountId ) return `accountId:${ account . accountId } ` ;
194- return `refreshToken:${ account . refreshToken } ` ;
193+ const organizationId = account . organizationId ?. trim ( ) ;
194+ const accountId = account . accountId ?. trim ( ) ;
195+ const refreshToken = account . refreshToken . trim ( ) ;
196+ if ( organizationId ) {
197+ return accountId
198+ ? `organizationId:${ organizationId } |accountId:${ accountId } `
199+ : `organizationId:${ organizationId } ` ;
200+ }
201+ if ( accountId ) return `accountId:${ accountId } ` ;
202+ return `refreshToken:${ refreshToken } ` ;
195203}
196204
197205function matchesWorkspaceIdentity (
@@ -205,6 +213,21 @@ function matchesWorkspaceIdentity(
205213 return getWorkspaceIdentityKey ( account ) === identityKey ;
206214}
207215
216+ function upsertFlaggedAccountRecord (
217+ accounts : FlaggedAccountMetadataV1 [ ] ,
218+ record : FlaggedAccountMetadataV1 ,
219+ ) : void {
220+ const identityKey = getWorkspaceIdentityKey ( record ) ;
221+ const existingIndex = accounts . findIndex ( ( flagged ) =>
222+ matchesWorkspaceIdentity ( flagged , identityKey ) ,
223+ ) ;
224+ if ( existingIndex >= 0 ) {
225+ accounts [ existingIndex ] = record ;
226+ return ;
227+ }
228+ accounts . push ( record ) ;
229+ }
230+
208231/**
209232 * OpenAI Codex OAuth authentication plugin for opencode
210233 *
@@ -2382,7 +2405,6 @@ while (attempted.size < Math.max(1, accountCount)) {
23822405
23832406 const workspaceDeactivated = isDeactivatedWorkspaceError ( errorBody , response . status ) ;
23842407 if ( workspaceDeactivated ) {
2385- const identityKey = getWorkspaceIdentityKey ( account ) ;
23862408 const accountLabel = formatAccountLabel ( account , account . index ) ;
23872409 accountManager . refundToken ( account , modelFamily , model ) ;
23882410 accountManager . recordFailure ( account , modelFamily , model ) ;
@@ -2393,22 +2415,20 @@ while (attempted.size < Math.max(1, accountCount)) {
23932415 runtimeMetrics . lastErrorCategory = "workspace-deactivated" ;
23942416
23952417 try {
2396- const flaggedStorage = await loadFlaggedAccounts ( ) ;
23972418 const flaggedRecord : FlaggedAccountMetadataV1 = {
23982419 ...account ,
23992420 flaggedAt : Date . now ( ) ,
24002421 flaggedReason : "workspace-deactivated" ,
24012422 lastError : "deactivated_workspace" ,
24022423 } ;
2403- const existingIndex = flaggedStorage . accounts . findIndex ( ( flagged ) =>
2404- matchesWorkspaceIdentity ( flagged , identityKey ) ,
2405- ) ;
2406- if ( existingIndex >= 0 ) {
2407- flaggedStorage . accounts [ existingIndex ] = flaggedRecord ;
2408- } else {
2409- flaggedStorage . accounts . push ( flaggedRecord ) ;
2410- }
2411- await saveFlaggedAccounts ( flaggedStorage ) ;
2424+ await withFlaggedAccountStorageTransaction ( async ( current , persist ) => {
2425+ const nextStorage : typeof current = {
2426+ ...current ,
2427+ accounts : current . accounts . map ( ( flagged ) => ( { ...flagged } ) ) ,
2428+ } ;
2429+ upsertFlaggedAccountRecord ( nextStorage . accounts , flaggedRecord ) ;
2430+ await persist ( nextStorage ) ;
2431+ } ) ;
24122432 } catch ( flagError ) {
24132433 logWarn (
24142434 `Failed to persist deactivated workspace flag for ${ accountLabel } : ${ flagError instanceof Error ? flagError . message : String ( flagError ) } ` ,
@@ -3074,9 +3094,9 @@ while (attempted.size < Math.max(1, accountCount)) {
30743094 return ;
30753095 }
30763096
3077- const flaggedStorage = await loadFlaggedAccounts ( ) ;
30783097 let storageChanged = false ;
30793098 let flaggedChanged = false ;
3099+ const flaggedUpdates = new Map < string , FlaggedAccountMetadataV1 > ( ) ;
30803100 const removeFromActive = new Set < string > ( ) ;
30813101 const total = workingStorage . accounts . length ;
30823102 let ok = 0 ;
@@ -3182,21 +3202,17 @@ while (attempted.size < Math.max(1, accountCount)) {
31823202 refreshResult . message ?? refreshResult . reason ?? "refresh failed" ;
31833203 console . log ( `[${ i + 1 } /${ total } ] ${ label } : ERROR (${ message } )` ) ;
31843204 if ( deepProbe && isFlaggableFailure ( refreshResult ) ) {
3185- const existingIndex = flaggedStorage . accounts . findIndex (
3186- ( flagged ) => flagged . refreshToken === account . refreshToken ,
3187- ) ;
31883205 const flaggedRecord : FlaggedAccountMetadataV1 = {
31893206 ...account ,
31903207 flaggedAt : Date . now ( ) ,
31913208 flaggedReason : "token-invalid" ,
31923209 lastError : message ,
31933210 } ;
3194- if ( existingIndex >= 0 ) {
3195- flaggedStorage . accounts [ existingIndex ] = flaggedRecord ;
3196- } else {
3197- flaggedStorage . accounts . push ( flaggedRecord ) ;
3198- }
3199- removeFromActive . add ( `refreshToken:${ account . refreshToken } ` ) ;
3211+ flaggedUpdates . set (
3212+ getWorkspaceIdentityKey ( flaggedRecord ) ,
3213+ flaggedRecord ,
3214+ ) ;
3215+ removeFromActive . add ( getWorkspaceIdentityKey ( account ) ) ;
32003216 flaggedChanged = true ;
32013217 }
32023218 continue ;
@@ -3279,20 +3295,16 @@ while (attempted.size < Math.max(1, accountCount)) {
32793295 errors += 1 ;
32803296 const message = error instanceof Error ? error . message : String ( error ) ;
32813297 if ( message . includes ( "deactivated_workspace" ) ) {
3282- const existingIndex = flaggedStorage . accounts . findIndex ( ( flagged ) =>
3283- matchesWorkspaceIdentity ( flagged , getWorkspaceIdentityKey ( account ) ) ,
3284- ) ;
32853298 const flaggedRecord : FlaggedAccountMetadataV1 = {
32863299 ...account ,
32873300 flaggedAt : Date . now ( ) ,
32883301 flaggedReason : "workspace-deactivated" ,
32893302 lastError : message ,
32903303 } ;
3291- if ( existingIndex >= 0 ) {
3292- flaggedStorage . accounts [ existingIndex ] = flaggedRecord ;
3293- } else {
3294- flaggedStorage . accounts . push ( flaggedRecord ) ;
3295- }
3304+ flaggedUpdates . set (
3305+ getWorkspaceIdentityKey ( flaggedRecord ) ,
3306+ flaggedRecord ,
3307+ ) ;
32963308 removeFromActive . add ( getWorkspaceIdentityKey ( account ) ) ;
32973309 flaggedChanged = true ;
32983310 }
@@ -3320,7 +3332,16 @@ while (attempted.size < Math.max(1, accountCount)) {
33203332 invalidateAccountManagerCache ( ) ;
33213333 }
33223334 if ( flaggedChanged ) {
3323- await saveFlaggedAccounts ( flaggedStorage ) ;
3335+ await withFlaggedAccountStorageTransaction ( async ( current , persist ) => {
3336+ const nextStorage : typeof current = {
3337+ ...current ,
3338+ accounts : current . accounts . map ( ( flagged ) => ( { ...flagged } ) ) ,
3339+ } ;
3340+ for ( const flaggedRecord of flaggedUpdates . values ( ) ) {
3341+ upsertFlaggedAccountRecord ( nextStorage . accounts , flaggedRecord ) ;
3342+ }
3343+ await persist ( nextStorage ) ;
3344+ } ) ;
33243345 }
33253346
33263347 console . log ( "" ) ;
@@ -3524,7 +3545,11 @@ while (attempted.size < Math.max(1, accountCount)) {
35243545 await saveFlaggedAccounts ( {
35253546 version : 1 ,
35263547 accounts : flaggedStorage . accounts . filter (
3527- ( flagged ) => flagged . refreshToken !== target . refreshToken ,
3548+ ( flagged ) =>
3549+ ! matchesWorkspaceIdentity (
3550+ flagged ,
3551+ getWorkspaceIdentityKey ( target ) ,
3552+ ) ,
35283553 ) ,
35293554 } ) ;
35303555 invalidateAccountManagerCache ( ) ;
0 commit comments