{"record":{"id":"5f3ffc931b77e20f","repo":"jlcodes99/cockpit-tools","slug":"provider-store-cachekey-5f3ffc","errorCode":null,"errorMessage":"[Provider Store] 忽略异常空账号列表，保留本地缓存: ${cacheKey}","messagePattern":"\\[Provider Store\\] 忽略异常空账号列表，保留本地缓存: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/stores/createProviderAccountStore.ts","lineNumber":269,"sourceCode":"    },\n\n    setCurrentAccountId: (accountId: string | null) => {\n      fetchCurrentAccountSeq += 1;\n      const currentAccountId = normalizeCurrentAccountId(accountId, get().accounts);\n      set({ currentAccountId });\n      persistCurrentAccountId(currentAccountId);\n    },\n\n    fetchAccounts: async () => {\n      const requestId = ++fetchAccountsSeq.current;\n      set({ loading: true, error: null });\n      try {\n        const accounts = await service.listAccounts();\n        if (requestId !== fetchAccountsSeq.current) {\n          return;\n        }\n        if (accounts.length === 0 && get().accounts.length > 0 && !allowNextEmptyAccountList) {\n          console.warn(`[Provider Store] 忽略异常空账号列表，保留本地缓存: ${cacheKey}`);\n          set({ loading: false });\n          return;\n        }\n        allowNextEmptyAccountList = false;\n        const mapped = mapAccountsForUnifiedView(accounts);\n        set({ accounts: mapped, loading: false });\n        persistAccountsCache(mapped);\n        await get().fetchCurrentAccountId();\n      } catch (e) {\n        if (requestId !== fetchAccountsSeq.current) {\n          return;\n        }\n        set({ error: String(e), loading: false });\n      } finally {\n        if (requestId === fetchAccountsSeq.current) {\n          allowNextEmptyAccountList = false;\n        }\n      }","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/stores/createProviderAccountStore.ts#L251-L287","documentation":"console.warn in createProviderAccountStore's fetchAccounts: the service returned an empty account list while the store still holds a non-empty local list and allowNextEmptyAccountList is false. The store treats the empty response as anomalous, keeps local cached accounts, and stops loading — protecting UI state from transient backend emptiness.","triggerScenarios":"service.listAccounts() resolves to [] while get().accounts.length > 0, allowNextEmptyAccountList is false, and the request is still current (requestId matches).","commonSituations":"Provider backend restarted or session expired returning empty instead of an auth error; API pagination/filter bug returning zero rows; network proxy stripping the payload; deliberate logout flows bypass this via allowNextEmptyAccountList.","solutions":["Ignore if transient — refetch accounts; a subsequent non-empty list applies normally.","If accounts truly were deleted, perform the deletion through the store so allowNextEmptyAccountList is set first.","Log in again if the provider session expired — an empty list can mask an auth failure.","Inspect the provider listAccounts response (raw network/backend log) for pagination or filter bugs.","Update the integration if the provider API changed its empty-list semantics."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const accounts = await service.listAccounts();\nif (accounts.length === 0 && get().accounts.length > 0 && !allowNextEmptyAccountList) {\n  console.warn(`[Provider Store] ignoring anomalous empty account list: ${cacheKey}`);\n  return; // keep cache\n}","typeGuard":"function isNonEmptyAccountList(v: unknown): v is Account[] {\n  return Array.isArray(v) && v.length > 0 &&\n    v.every(a => typeof a === 'object' && a !== null && 'id' in a);\n}","tryCatchPattern":null,"preventionTips":["Set allowNextEmptyAccountList before intentional destructive flows (logout, delete-all).","Validate that listAccounts empty results are not masking auth errors — check session first.","Add stale-while-revalidate semantics so users see cached data while re-verifying with the backend."],"tags":["state-management","zustand","cache","accounts"],"backgroundTag":"empty-account-list-guard","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}