{"record":{"id":"1b64b5788d492dd9","repo":"Mintplex-Labs/anything-llm","slug":"response-error-failed-to-fetch-settings","errorCode":null,"errorMessage":"${response.error || \"Failed to fetch settings\"}","messagePattern":"\\$\\{response\\.error \\|\\| \"Failed to fetch settings\"\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/models/communityHub.js","lineNumber":107,"sourceCode":"      .catch((e) => ({\n        success: false,\n        error: e.message,\n      }));\n  },\n\n  /**\n   * Get the hub settings (API key, etc.)\n   * @returns {Promise<{connectionKey: string | null, error: string | null}>}\n   */\n  getSettings: async () => {\n    return await fetch(`${API_BASE}/community-hub/settings`, {\n      method: \"GET\",\n      headers: baseHeaders(),\n    })\n      .then(async (res) => {\n        const response = await res.json();\n        if (!res.ok)\n          throw new Error(response.error || \"Failed to fetch settings\");\n        return { connectionKey: response.connectionKey, error: null };\n      })\n      .catch((e) => ({\n        connectionKey: null,\n        error: e.message,\n      }));\n  },\n\n  /**\n   * Fetch the explore items from the community hub that are publicly available.\n   * @returns {Promise<{agentSkills: {items: [], hasMore: boolean, totalCount: number}, systemPrompts: {items: [], hasMore: boolean, totalCount: number}, slashCommands: {items: [], hasMore: boolean, totalCount: number}}>}\n   */\n  fetchExploreItems: async () => {\n    return await fetch(`${API_BASE}/community-hub/explore`, {\n      method: \"GET\",\n      headers: baseHeaders(),\n    })\n      .then((res) => res.json())","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/frontend/src/models/communityHub.js#L89-L125","documentation":"Thrown from `getSettings` on a non-ok `GET /api/community-hub/settings`. Reads `response.error` from JSON, falling back to 'Failed to fetch settings'. Returns `{ connectionKey, error }`. Mostly a read failure: auth, backend, or persistence.","triggerScenarios":"401/403 (non-admin or expired session), 500 backend settings store error, network failure (covered by catch), malformed response body causing `.json()` to throw.","commonSituations":"Loading the community-hub settings page after session expiry; backend migration that changed the settings shape; reverse proxy returning HTML (login page) so JSON parse fails.","solutions":["On 401, redirect to login and re-fetch after auth.","Read `error` from the returned object for the backend's reason.","Ensure the response is JSON (not an HTML login redirect) — guard the `res.json()` call.","Check backend logs for the 500 root cause."],"exampleFix":"// before\nconst { connectionKey, error } = await CommunityHub.getSettings();\n\n// after — guard parse + handle auth\nconst { connectionKey, error } = await CommunityHub.getSettings();\nif (error && /401|unauthor/i.test(error)) {\n  await redirectToLogin();\n  return;\n}\nif (error) throw new Error(error);","handlingStrategy":"try-catch","validationCode":"// Mostly a read; pre-check auth state:\nfunction assertAuthed() {\n  if (!getToken()) throw new Error('Not authenticated');\n}","typeGuard":"function isAuthOrParseError(msg) { return /401|unauthor|Unexpected token|JSON/i.test(String(msg || '')); }","tryCatchPattern":"const { connectionKey, error } = await CommunityHub.getSettings();\nif (error) {\n  if (/401|unauthor/i.test(error)) { await redirectToLogin(); return; }\n  showToast(error);\n}","preventionTips":["Redirect to login on 401 before rendering the settings page.","Guard `res.json()` against HTML login redirects in the model.","Check backend logs for 500 root causes."],"tags":["frontend","community-hub","settings","network","fetch"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}