@@ -1478,7 +1478,7 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
14781478 ) ;
14791479 }
14801480
1481- while ( attempted . size < Math . max ( 1 , accountCount ) ) {
1481+ accountAttemptLoop: while ( attempted . size < Math . max ( 1 , accountCount ) ) {
14821482 let account = null ;
14831483 if (
14841484 ! usedPreferredSessionAccount &&
@@ -1967,75 +1967,84 @@ while (attempted.size < Math.max(1, accountCount)) {
19671967 blockedModel ,
19681968 ) ;
19691969 }
1970- if ( errorResponse . status === 403 && ! unsupportedModelInfo . isUnsupported ) {
1971- entitlementCache . markBlocked (
1972- entitlementAccountKey ,
1973- model ?? modelFamily ,
1974- "plan-entitlement" ,
1975- ) ;
1976- capabilityPolicyStore . recordFailure (
1977- entitlementAccountKey ,
1978- capabilityModelKey ,
1970+ const workspaceErrorCode =
1971+ ( errorBody as { error ?: { code ?: string } } | undefined ) ?. error ?. code ?? "" ;
1972+ const workspaceErrorMessage =
1973+ ( errorBody as { error ?: { message ?: string } } | undefined ) ?. error ?. message ?? "" ;
1974+ const isDisabledWorkspaceError =
1975+ errorResponse . status === 403 &&
1976+ isWorkspaceDisabledError (
1977+ errorResponse . status ,
1978+ workspaceErrorCode ,
1979+ workspaceErrorMessage ,
19791980 ) ;
1980- }
19811981
19821982 // Handle workspace disabled/expired errors by rotating to next workspace within account
1983- if ( errorResponse . status === 403 && errorBody ) {
1984- const errorCode = ( errorBody as { error ?: { code ?: string } } ) ?. error ?. code ?? "" ;
1985- const errorMessage = ( errorBody as { error ?: { message ?: string } } ) ?. error ?. message ?? "" ;
1986-
1987- if ( isWorkspaceDisabledError ( errorResponse . status , errorCode , errorMessage ) ) {
1983+ if ( isDisabledWorkspaceError ) {
19881984 runtimeMetrics . failedRequests ++ ;
19891985 runtimeMetrics . lastError = `Workspace disabled for account ${ account . index + 1 } ` ;
1990-
1986+
19911987 // Get current workspace info for logging
19921988 const currentWorkspace = accountManager . getCurrentWorkspace ( account ) ;
19931989 const workspaceName = currentWorkspace ?. name ?? currentWorkspace ?. id ?? "unknown" ;
1994-
1990+
19951991 logWarn (
1996- `Workspace disabled/expired for account ${ account . index + 1 } ( ${ account . email ?? "unknown" } ) - workspace: ${ workspaceName } . Rotating to next workspace.` ,
1997- { errorCode, errorMessage } ,
1992+ `Workspace disabled/expired for account ${ account . index + 1 } - workspace: ${ workspaceName } . Rotating to next workspace.` ,
1993+ { errorCode : workspaceErrorCode } ,
19981994 ) ;
1999-
1995+
20001996 // Disable the current workspace
20011997 accountManager . disableCurrentWorkspace ( account ) ;
2002-
1998+
20031999 // Try to rotate to next enabled workspace
20042000 const nextWorkspace = accountManager . rotateToNextWorkspace ( account ) ;
2005-
2001+
20062002 if ( nextWorkspace ) {
2007- // Found another enabled workspace, retry with it
2003+ // Found another enabled workspace, persist it and restart the
2004+ // outer account loop so accountId and headers are rebuilt.
20082005 accountManager . saveToDiskDebounced ( ) ;
2009-
2006+
20102007 const newWorkspaceName = nextWorkspace . name ?? nextWorkspace . id ;
20112008 await showToast (
20122009 `Workspace ${ workspaceName } disabled. Switched to ${ newWorkspaceName } .` ,
20132010 "warning" ,
20142011 { duration : toastDurationMs } ,
20152012 ) ;
2016-
2013+
20172014 logInfo ( `Rotated to workspace ${ newWorkspaceName } for account ${ account . index + 1 } ` ) ;
2018-
2019- // Retry the request with the new workspace (continue the loop)
2020- continue ;
2015+
2016+ // Allow the same account to be selected again with fresh request state.
2017+ attempted . delete ( account . index ) ;
2018+ continue accountAttemptLoop;
20212019 } else {
20222020 // No more enabled workspaces, disable the entire account
20232021 logWarn ( `All workspaces disabled for account ${ account . index + 1 } . Disabling account.` ) ;
2024-
2022+
20252023 accountManager . setAccountEnabled ( account . index , false ) ;
20262024 accountManager . saveToDiskDebounced ( ) ;
2027-
2025+
20282026 await showToast (
20292027 `All workspaces disabled for account ${ account . index + 1 } . Switching to another account.` ,
20302028 "warning" ,
20312029 { duration : toastDurationMs } ,
20322030 ) ;
2033-
2031+
20342032 // Forget session affinity and rotate to next account
20352033 sessionAffinityStore ?. forgetSession ( sessionAffinityKey ) ;
20362034 break ;
20372035 }
2038- }
2036+ }
2037+
2038+ if ( errorResponse . status === 403 && ! unsupportedModelInfo . isUnsupported && ! isDisabledWorkspaceError ) {
2039+ entitlementCache . markBlocked (
2040+ entitlementAccountKey ,
2041+ model ?? modelFamily ,
2042+ "plan-entitlement" ,
2043+ ) ;
2044+ capabilityPolicyStore . recordFailure (
2045+ entitlementAccountKey ,
2046+ capabilityModelKey ,
2047+ ) ;
20392048 }
20402049
20412050 if ( recoveryHook && errorBody && isRecoverableError ( errorBody ) ) {
0 commit comments