Mintplex-Labs/anything-llm · error

Failed to fetch edited image

Error message

Failed to fetch edited image: ${imgRes.status}

What it means

In editImage(), when the provider replies with an image URL instead of base64, AnythingLLM downloads that URL with fetch and throws 'Failed to fetch edited image: <status>' on any non-2xx. The edit itself succeeded; only the follow-up retrieval of the produced image bytes failed.

Solutions

  1. Retry the edit promptly — a fresh request yields a fresh URL.
  2. Allow egress from the AnythingLLM host to the provider's CDN/image domain (proxy, firewall, DNS).
  3. Prefer a model/settings that return b64_json inline (gpt-image-1 always does), skipping the download.
  4. Map the status: 403/401 → link access problem, 404 → expired URL, 5xx → provider CDN incident.
Defensive patterns

Strategy: retry

Try / catch

async function editWithRetry(generator, params, maxAttempts = 2) {
  for (let i = 1; ; i++) {
    try {
      return await generator.editImage(params);
    } catch (err) {
      if (
        err.message.startsWith("Failed to fetch edited image:") &&
        i < maxAttempts
      ) {
        continue; // a fresh edit gets a fresh, unexpired URL
      }
      throw err;
    }
  }
}

Prevention

When it happens

Trigger: The provider's signed CDN URL expired before the fetch ran; the server cannot reach the image host (egress firewall, docker without external DNS); the CDN returns 403/429 for bot checks or hotlink protection; the image store evicted the object between edit and download.

Common situations: Short-lived signed URLs (Azure-style) with any processing delay; air-gapped or proxied deployments that whitelist only the API host but not its CDN.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@f92433b4ea (2026-08-18). Data as JSON: /api/errors/f5d54c42207bacfa. Report an issue: GitHub.

Appendix: source

Thrown at server/utils/ImageGenerators/base.js:103

      signal: signal ?? null,
    });

    if (!res.ok) {
      const body = await res.text().catch(() => "");
      throw new Error(
        `Image edit failed (${res.status}): ${body || res.statusText}`
      );
    }

    const payload = await res.json();
    const image = payload?.data?.[0];
    let result;
    if (image?.b64_json) {
      result = { buffer: Buffer.from(image.b64_json, "base64") };
    } else if (image?.url) {
      const imgRes = await fetch(image.url, { signal: signal ?? null });
      if (!imgRes.ok)
        throw new Error(`Failed to fetch edited image: ${imgRes.status}`);
      result = { buffer: Buffer.from(await imgRes.arrayBuffer()) };
    } else {
      throw new Error("Image edit returned no image data.");
    }
    this._sendImageTelemetry("image_generated", {
      withReferences: images.length > 0,
    });
    return result;
  }

  /**
   * Emits a telemetry event if Telemetry is turned on.
   * @param {string} event
   * @param {Object} [additionalOpts]
   */
  _sendImageTelemetry(event, additionalOpts = {}) {
    const { Telemetry } = require("../../models/telemetry");
    Telemetry.sendTelemetry(event, {

View on GitHub (pinned to f92433b4ea)