{"record":{"id":"4f04ad4ddd182a3f","repo":"decolua/9router","slug":"all-accounts-unavailable-4f04ad","errorCode":null,"errorMessage":"All accounts unavailable","messagePattern":"All accounts unavailable","errorType":"http","errorClass":null,"httpStatus":503,"severity":"error","filePath":"src/sse/handlers/embeddings.js","lineNumber":112,"sourceCode":"  let lastError = null;\n  let lastStatus = null;\n\n  while (true) {\n    const credentials = await getProviderCredentials(provider, excludeConnectionIds, model);\n\n    // All accounts unavailable\n    if (!credentials || credentials.allRateLimited) {\n      if (credentials?.allRateLimited) {\n        const errorMsg = lastError || credentials.lastError || \"Unavailable\";\n        const status = lastStatus || Number(credentials.lastErrorCode) || HTTP_STATUS.SERVICE_UNAVAILABLE;\n        log.warn(\"EMBEDDINGS\", `[${provider}/${model}] ${errorMsg} (${credentials.retryAfterHuman})`);\n        return unavailableResponse(status, `[${provider}/${model}] ${errorMsg}`, credentials.retryAfter, credentials.retryAfterHuman);\n      }\n      if (excludeConnectionIds.size === 0) {\n        log.error(\"AUTH\", `No credentials for provider: ${provider}`);\n        return errorResponse(HTTP_STATUS.BAD_REQUEST, `No credentials for provider: ${provider}`);\n      }\n      log.warn(\"EMBEDDINGS\", \"No more accounts available\", { provider });\n      return errorResponse(lastStatus || HTTP_STATUS.SERVICE_UNAVAILABLE, lastError || \"All accounts unavailable\");\n    }\n\n    log.info(\"AUTH\", `\\x1b[32mUsing ${provider} account: ${credentials.connectionName}\\x1b[0m`);\n\n    const refreshedCredentials = await checkAndRefreshToken(provider, credentials);\n\n    const result = await handleEmbeddingsCore({\n      body: { ...body, model: `${provider}/${model}` },\n      modelInfo: { provider, model },\n      credentials: refreshedCredentials,\n      log,\n      onCredentialsRefreshed: async (newCreds) => {\n        await updateProviderCredentials(credentials.connectionId, {\n          ...newCreds,\n          existingProviderSpecificData: credentials.providerSpecificData,\n          testStatus: \"active\"\n        });","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/sse/handlers/embeddings.js#L94-L130","documentation":"HTTP 503 (or lastStatus) returned when the provider has credentials configured but every candidate account was tried and excluded via markAccountUnavailable during this request's fallback loop — none succeeded and none are flagged merely rate-limited. lastError carries the final upstream failure reason.","triggerScenarios":"getProviderCredentials returns null while excludeConnectionIds.size > 0, i.e. the request already cycled through all accounts and each failed with shouldFallback=true.","commonSituations":"All provider accounts have expired/invalid tokens that refresh cannot fix; upstream provider-wide outage; wrong credentials entered for every account; embedding job large enough to exhaust all accounts' quotas mid-run.","solutions":["Inspect the dashboard account list and re-authenticate/fix failing connections","Check the router log for the underlying lastError of each failed account","Add a healthy fallback provider or combo route","Wait for the upstream outage to resolve and clear account error states","Verify tokens are valid via the dashboard's connection test button"],"exampleFix":"// before\nawait embed({ model: 'provider/x', input }); // fails 503\n// after\ntry {\n  return await embed({ model: 'provider/x', input });\n} catch (e) {\n  return await embed({ model: 'fallback-provider/x', input }); // combo/alternate route\n}","handlingStrategy":"fallback","validationCode":"// Before large jobs, confirm at least one healthy account via a tiny probe\nconst probe = await post('/v1/embeddings', { model, input: ['ping'] });\nif (!probe.ok && probe.status >= 500) throw new Error('Provider accounts unhealthy — check dashboard');","typeGuard":null,"tryCatchPattern":"try {\n  return await post('/v1/embeddings', payload);\n} catch (e) {\n  if (e.status === 503) return post('/v1/embeddings', { ...payload, model: fallbackModel });\n  throw e;\n}","preventionTips":["Keep a second provider configured as fallback","Fix/refresh failing connections promptly in the dashboard","Alert on lastError appearing in router logs","Clear stale unavailable flags after upstream recovers"],"tags":["availability","fallback-exhausted","service-unavailable"],"backgroundTag":"all-accounts-unavailable","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}