Mintplex-Labs/anything-llm · warning · Error

Failed to fetch image

Error message

Failed to fetch image

What it means

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.

Source

Thrown at frontend/src/models/files.js:37

      .catch((e) => {
        console.error("Download failed:", e);
        return null;
      });
  },

  /**
   * Fetch a generated image as a Blob. The serve endpoint is auth-protected, so
   * we cannot use the URL directly as an <img> src - callers create an object URL.
   * @param {string} storageFilename - The image filename to fetch
   * @returns {Promise<Blob|null>}
   */
  image: async function (storageFilename) {
    return await fetch(
      `${API_BASE}/image-generation/generated-images/${encodeURIComponent(storageFilename)}`,
      { headers: baseHeaders() }
    )
      .then((res) => {
        if (!res.ok) throw new Error("Failed to fetch image");
        return res.blob();
      })
      .catch((e) => {
        console.error("Image fetch failed:", e);
        return null;
      });
  },
};

export default StorageFiles;

View on GitHub (pinned to 526360e320)

Solutions

  1. Inspect DevTools Network for the generated-images request status and WWW-Authenticate/response body.
  2. Confirm localStorage AUTH_TOKEN is set (the endpoint requires it unlike the public logo route).
  3. On the server, diff the image-generation output directory against the directory the serve route reads from.
  4. Validate that storageFilename is the server-side stored name, not the original upload name.

Example fix

// before
const blob = await StorageFiles.image(name);
setSrc(blob ? URL.createObjectURL(blob) : "");

// after
const blob = await StorageFiles.image(name);
if (!blob) {
  setSrc(fallbackPlaceholder);
  return;
}
setSrc(URL.createObjectURL(blob));
Defensive patterns

Strategy: validation

Validate before calling

function validImageName(name) {
  return typeof name === "string" && /\.(png|jpe?g|webp|gif|svg)$/i.test(name);
}
// Also ensure AUTH_TOKEN is set since the route is auth-protected.

Type guard

/** @param {any} r @returns {r is Blob} */
function isImageBlob(r) { return r instanceof Blob && r.type.startsWith("image/"); }

Try / catch

const blob = await StorageFiles.image(name);
if (!isImageBlob(blob)) { setSrc(placeholder); return; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/79b0044de5193550. Report an issue: GitHub.