{"record":{"id":"79b0044de5193550","repo":"Mintplex-Labs/anything-llm","slug":"failed-to-fetch-image","errorCode":null,"errorMessage":"Failed to fetch image","messagePattern":"Failed to fetch image","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/src/models/files.js","lineNumber":37,"sourceCode":"      .catch((e) => {\n        console.error(\"Download failed:\", e);\n        return null;\n      });\n  },\n\n  /**\n   * Fetch a generated image as a Blob. The serve endpoint is auth-protected, so\n   * we cannot use the URL directly as an <img> src - callers create an object URL.\n   * @param {string} storageFilename - The image filename to fetch\n   * @returns {Promise<Blob|null>}\n   */\n  image: async function (storageFilename) {\n    return await fetch(\n      `${API_BASE}/image-generation/generated-images/${encodeURIComponent(storageFilename)}`,\n      { headers: baseHeaders() }\n    )\n      .then((res) => {\n        if (!res.ok) throw new Error(\"Failed to fetch image\");\n        return res.blob();\n      })\n      .catch((e) => {\n        console.error(\"Image fetch failed:\", e);\n        return null;\n      });\n  },\n};\n\nexport default StorageFiles;\n","sourceCodeStart":19,"sourceCodeEnd":48,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/frontend/src/models/files.js#L19-L48","documentation":"Thrown by StorageFiles.image when the GET to /api/image-generation/generated-images/{storageFilename} returns a non-2xx status. The serve endpoint is auth-protected (per the JSDoc), so the image cannot be used directly as an <img> src; callers must fetch it as a Blob and build an object URL. As with download(), the .catch() returns null, hiding the underlying HTTP failure.","triggerScenarios":"Calling StorageFiles.image(\"gen-abc.png\") when the image was never persisted (404), when the image-generation storage directory differs from the serve root, or when the Bearer token in localStorage is missing/expired (401/403) since the route is auth-protected.","commonSituations":"Image-generation provider wrote to a different mount than the serve path; the deployment was moved/redeployed and generated-images were not migrated; the user's session lapsed mid-gallery-view.","solutions":["Inspect DevTools Network for the generated-images request status and WWW-Authenticate/response body.","Confirm localStorage AUTH_TOKEN is set (the endpoint requires it unlike the public logo route).","On the server, diff the image-generation output directory against the directory the serve route reads from.","Validate that storageFilename is the server-side stored name, not the original upload name."],"exampleFix":"// before\nconst blob = await StorageFiles.image(name);\nsetSrc(blob ? URL.createObjectURL(blob) : \"\");\n\n// after\nconst blob = await StorageFiles.image(name);\nif (!blob) {\n  setSrc(fallbackPlaceholder);\n  return;\n}\nsetSrc(URL.createObjectURL(blob));","handlingStrategy":"validation","validationCode":"function validImageName(name) {\n  return typeof name === \"string\" && /\\.(png|jpe?g|webp|gif|svg)$/i.test(name);\n}\n// Also ensure AUTH_TOKEN is set since the route is auth-protected.","typeGuard":"/** @param {any} r @returns {r is Blob} */\nfunction isImageBlob(r) { return r instanceof Blob && r.type.startsWith(\"image/\"); }","tryCatchPattern":"const blob = await StorageFiles.image(name);\nif (!isImageBlob(blob)) { setSrc(placeholder); return; }","preventionTips":["Validate the filename looks like an image before the network call.","Provide a placeholder image so a null return does not break the layout.","Cache object URLs and revoke them on unmount."],"tags":["network","image","auth","image-generation"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}