Mintplex-Labs/anything-llm · error · Error

Error downloading model: ${response.statusText}

Error message

Error downloading model: ${response.statusText}

What it means

Thrown by DmrUtils.downloadModel when POST /utils/dmr/download-model returns non-2xx before the streaming reader is attached. The endpoint streams Server-Sent-Events (data: lines with progress/success/error payloads). The thrown message concatenates response.statusText, so the underlying reason depends on the server's reason phrase. The outer Promise executor catches and resolves { success: false, error }.

Source

Thrown at frontend/src/models/utils/dmrUtils.js:27

   * @param {(percentage: number) => void} progressCallback - The callback to receive the progress percentage. If the model is already downloaded, it will be called once with 100.
   * @returns {Promise<{success: boolean, error: string|null}>}
   */
  downloadModel: async function (
    modelId,
    basePath = "",
    progressCallback = () => {}
  ) {
    // eslint-disable-next-line no-async-promise-executor
    return new Promise(async (resolve) => {
      try {
        const response = await fetch(`${API_BASE}/utils/dmr/download-model`, {
          method: "POST",
          headers: baseHeaders(),
          body: JSON.stringify({ modelId, basePath }),
        });

        if (!response.ok)
          throw new Error("Error downloading model: " + response.statusText);
        const reader = response.body.getReader();
        let done = false;

        while (!done) {
          const { value, done: readerDone } = await reader.read();
          if (readerDone) {
            done = true;
            resolve({ success: true });
          } else {
            const chunk = new TextDecoder("utf-8").decode(value);
            const lines = chunk.split("\n");
            for (const line of lines) {
              if (line.startsWith("data:")) {
                const data = safeJsonParse(line.slice(5));
                switch (data?.type) {
                  case "success":
                    done = true;
                    resolve({ success: true });

View on GitHub (pinned to 526360e320)

Solutions

  1. Read the Network tab response body for /utils/dmr/download-model — statusText is often unhelpful.
  2. Verify modelId exists in the DMR catalog via the model-list endpoint before invoking downloadModel.
  3. Confirm basePath is writable by the backend process and has sufficient free space.
  4. Improve the thrown message to include res.status and the response body for diagnosis.

Example fix

// before
if (!response.ok)
  throw new Error("Error downloading model: " + response.statusText);

// after
if (!response.ok) {
  const body = await response.text().catch(() => "");
  throw new Error(`Error downloading model (HTTP ${response.status}): ${body.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify modelId is in the catalog and basePath is writable-shaped before download.
async function modelExistsInCatalog(modelId) {
  const r = await fetch(`${API_BASE}/utils/dmr/models`, { headers: baseHeaders() });
  if (!r.ok) return false;
  const list = await r.json();
  return Array.isArray(list) && list.some(m => m.id === modelId);
}

Type guard

function isDownloadResult(x): x is { success: boolean; error?: string } {
  return x && typeof x.success === 'boolean';
}

Try / catch

const { success, error } = await DmrUtils.downloadModel(modelId, basePath, onProgress);
if (!success) {
  showDownloadError(error || 'Download failed.');
  return;
}

Prevention

When it happens

Trigger: The DMR (Device Model Registry) backend is unavailable, modelId is unknown to the registry, basePath points to a non-writable directory, or the user is not authorized to download models.

Common situations: modelId copied from a different DMR version that no longer exists; basePath on a read-only mount; backend DMR service crashed or never started; disk full so the backend rejects before streaming; HTTP/2 response with empty statusText yields the bare 'Error downloading model: ' prefix.

Related errors


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