{"record":{"id":"cb3f477ab3b4b231","repo":"gitroomhq/postiz-app","slug":"failed-to-load-stats","errorCode":null,"errorMessage":"Failed to load stats","messagePattern":"Failed to load stats","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/frontend/src/components/admin/admin-stats.component.tsx","lineNumber":79,"sourceCode":"\nconst useStats = (params: {\n  from: string;\n  to: string;\n  unknownOnly: boolean;\n}) => {\n  const fetch = useFetch();\n  const query = new URLSearchParams({\n    from: params.from,\n    to: params.to,\n    ...(params.unknownOnly ? { unknownOnly: 'true' } : {}),\n  });\n  const key = `/admin/stats?${query.toString()}`;\n  return useSWR<StatsResponse>(\n    key,\n    async (url: string) => {\n      const res = await fetch(url);\n      if (!res.ok) {\n        throw new Error('Failed to load stats');\n      }\n      return res.json();\n    },\n    {\n      revalidateOnFocus: false,\n      revalidateOnReconnect: false,\n    }\n  );\n};\n\nconst SummaryCard: FC<{ label: string; value: number }> = ({\n  label,\n  value,\n}) => (\n  <div className=\"border border-newTableBorder rounded-[8px] p-[16px] bg-newBgColorInner\">\n    <div className=\"text-[12px] opacity-70\">{label}</div>\n    <div className=\"text-[28px] font-[600]\">{value.toLocaleString()}</div>\n  </div>","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/frontend/src/components/admin/admin-stats.component.tsx#L61-L97","documentation":"The admin stats component's useStats SWR hook fetches /admin/stats and throws 'Failed to load stats' on any non-ok response. Same generic-wrap pattern as the errors hook; root cause is the HTTP status, typically 401/403 auth or a backend error.","triggerScenarios":"Non-admin or unauthenticated user loading the admin dashboard; expired session token; backend route error (500) while computing stats; query params producing a validation 400.","commonSituations":"Leaving the admin tab open past session expiry (SWR revalidates on focus and gets 401); role misconfiguration; backend migration breaking the stats aggregation query.","solutions":["Check the network tab for the real status on /admin/stats","Re-authenticate if 401; verify admin role if 403","Inspect backend logs if 500 — often a failing stats aggregation query","Include status/body in the error message and show a session-expired toast for 401"],"exampleFix":"// before\nif (!res.ok) throw new Error('Failed to load stats');\n\n// after\nif (!res.ok) {\n  if (res.status === 401) throw new Error('Session expired — please sign in again');\n  throw new Error(`Failed to load stats (${res.status})`);\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"const { data, error } = useStats();\nif (error) showBanner(error.status === 401 ? 'Session expired' : 'Stats unavailable');","preventionTips":["Surface HTTP status in SWR fetchers","Disable revalidateOnFocus where 401 noise is common, or handle expiry globally","Verify admin role before rendering the admin dashboard"],"tags":["admin","swr","frontend","fetch"],"backgroundTag":"http-request-non-ok","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}