{"record":{"id":"fd45c8e782585752","repo":"Mintplex-Labs/anything-llm","slug":"error-uploading-pfp","errorCode":null,"errorMessage":"Error uploading pfp.","messagePattern":"Error uploading pfp\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/models/system.js","lineNumber":310,"sourceCode":"    return await fetch(`${API_BASE}/system/remove-folder`, {\n      method: \"DELETE\",\n      headers: baseHeaders(),\n      body: JSON.stringify({ name }),\n    })\n      .then((res) => res.ok)\n      .catch((e) => {\n        console.error(e);\n        return false;\n      });\n  },\n  uploadPfp: async function (formData) {\n    return await fetch(`${API_BASE}/system/upload-pfp`, {\n      method: \"POST\",\n      body: formData,\n      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) => {","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/20f6d3546c1938bfea1ad304f58a592dddcc5948/frontend/src/models/system.js#L292-L328","documentation":"Thrown by uploadPfp in the AnythingLLM frontend when POST /api/system/upload-pfp (multipart FormData with the image) responds non-2xx; the message is fixed and hides the actual status. baseHeaders() only adds Authorization/X-Timezone/X-Language, so the browser still sets the multipart boundary correctly — a non-2xx here is a server-side rejection (auth, validation, or storage failure), not a header problem.","triggerScenarios":"Uploading a non-image or an image the server rejects; a file over the server's size limit (413); no auth token in localStorage so the Authorization header is null (401); the server's storage output folder not writable, making the write fail (500).","commonSituations":"Docker installs where the storage volume is read-only or owned by another user; dragging a HEIC/AVIF file the processor cannot handle; session expired after a long idle before saving the profile.","solutions":["Re-upload a standard PNG or JPEG within the size limit.","Confirm you are still logged in (token present in localStorage so Authorization is sent).","On self-hosted: verify the server's storage output folder is writable by the app user; check server logs for the 500.","Check the Network tab status code to distinguish 401 (auth), 413 (size), and 500 (storage)."],"exampleFix":"// before — post whatever the file input produced\nconst { success, error } = await System.uploadPfp(formData);\n\n// after — validate the file before building FormData\nif (!file.type.startsWith('image/')) return showError('Choose an image file');\nif (file.size > MAX_AVATAR_BYTES) return showError('Image is too large');\nconst { success, error } = await System.uploadPfp(formData);","handlingStrategy":"validation","validationCode":"// run before System.uploadPfp\nconst MAX_BYTES = 5 * 1024 * 1024;\nif (!(file instanceof File) || !file.type.startsWith('image/')) {\n  throw new Error('Choose a PNG or JPEG image');\n}\nif (file.size > MAX_BYTES) throw new Error('Image exceeds the size limit');","typeGuard":"/** @param {any} f @returns {f is File} */\nfunction isImageFile(f) {\n  return f instanceof File && f.type.startsWith('image/') && f.size > 0;\n}","tryCatchPattern":"const { success, error } = await System.uploadPfp(formData);\nif (!success) {\n  showUploadError(error); // 'Error uploading pfp.' — check Network tab for the real status\n  return;\n}","preventionTips":["Validate MIME type and size client-side before building FormData.","Keep sessions short-lived UIs re-authed; uploads are the first to fail on 401.","On self-hosted, verify the storage output folder is writable by the app user."],"tags":["anythingllm","file-upload","profile-picture","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"}