{"record":{"id":"25fcab37635b11ac","repo":"Mintplex-Labs/anything-llm","slug":"error-uploading-logo","errorCode":null,"errorMessage":"Error uploading logo.","messagePattern":"Error uploading logo\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/models/system.js","lineNumber":325,"sourceCode":"      headers: baseHeaders(),\n    })\n      .then((res) => {\n        if (!res.ok) throw new Error(\"Error uploading pfp.\");\n        return { success: true, error: null };\n      })\n      .catch((e) => {\n        console.log(e);\n        return { success: false, error: e.message };\n      });\n  },\n  uploadLogo: async function (formData) {\n    return await fetch(`${API_BASE}/system/upload-logo`, {\n      method: \"POST\",\n      body: formData,\n      headers: baseHeaders(),\n    })\n      .then((res) => {\n        if (!res.ok) throw new Error(\"Error uploading logo.\");\n        return { success: true, error: null };\n      })\n      .catch((e) => {\n        console.log(e);\n        return { success: false, error: e.message };\n      });\n  },\n  fetchCustomFooterIcons: async function () {\n    const cache = window.localStorage.getItem(this.cacheKeys.footerIcons);\n    const { data, lastFetched } = cache\n      ? safeJsonParse(cache, { data: [], lastFetched: 0 })\n      : { data: [], lastFetched: 0 };\n\n    if (!!data && Date.now() - lastFetched < 3_600_000)\n      return { footerData: data, error: null };\n\n    const { footerData, error } = await fetch(\n      `${API_BASE}/system/footer-data`,","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/20f6d3546c1938bfea1ad304f58a592dddcc5948/frontend/src/models/system.js#L307-L343","documentation":"Thrown by uploadLogo in the AnythingLLM frontend when POST /api/system/upload-logo (multipart FormData) responds non-2xx, with the fixed message 'Error uploading logo.'. This is an admin-facing system branding route, so besides the file/storage failures it also rejects non-admin sessions with 403.","triggerScenarios":"A non-admin (e.g. manager/default user) token calling the route (403); a non-image or oversized logo file; unwritable storage output directory on the server (500); expired session (401).","commonSituations":"A non-admin account trying to brand the instance; a multi-megabyte PNG logo pushed through a proxy with a small client_max_body_size; storage volume permissions changed after a migration.","solutions":["Make sure you are logged in as an admin (or have been granted the branding permission).","Upload a reasonably sized PNG/JPEG/SVG as accepted by the server.","If a reverse proxy fronts the app, raise its request body limit so the multipart upload is not cut off.","Check server logs and the Network status code for storage/permission errors."],"exampleFix":"// before\nconst { success, error } = await System.uploadLogo(formData);\n\n// after — gate on role and file size first\nif (user.role !== 'admin') return showError('Only admins can change the logo');\nif (file.size > MAX_LOGO_BYTES) return showError('Logo file is too large');\nconst { success, error } = await System.uploadLogo(formData);","handlingStrategy":"validation","validationCode":"// run before System.uploadLogo\nif (user?.role !== 'admin') throw new Error('Only admins can upload a logo');\nif (!(file instanceof File) || !file.type.startsWith('image/')) {\n  throw new Error('Logo must be an image file');\n}","typeGuard":null,"tryCatchPattern":"const { success, error } = await System.uploadLogo(formData);\nif (!success) {\n  showBrandingError(error); // 'Error uploading logo.' — correlate with Network status\n  return;\n}","preventionTips":["Gate the branding UI on the admin role so non-admins never reach the call.","Keep logo files small so reverse-proxy body limits do not truncate the upload.","Check storage volume permissions whenever the container or volume changes."],"tags":["anythingllm","file-upload","branding","admin","http"],"backgroundTag":"file-upload-rejected","analyzedSha":"20f6d3546c1938bfea1ad304f58a592dddcc5948","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}