Mintplex-Labs/anything-llm · error · Error

Error downloading model

Error message

Error downloading model: ${response.statusText}

What it means

Thrown by the DMR (model router) download helper in the AnythingLLM frontend before any progress is read: POST /api/utils/dmr/download-model responded non-2xx. The message concatenates the fixed prefix with response.statusText. The endpoint normally streams NDJSON progress while the server-side DMR CLI pulls the model, so this throw means the download never started.

Solutions

  1. Confirm the DMR tool is installed and invocable server-side; test the same download from its CLI.
  2. Double-check the modelId against the DMR model registry.
  3. Check free disk space and write permissions on basePath.
  4. Inspect server logs and the Network status code (4xx vs 5xx) for the underlying spawn error.
Defensive patterns

Strategy: validation

Validate before calling

// run before dmr downloadModel
if (!modelId || typeof modelId !== 'string') throw new Error('modelId is required');
if (!basePath) throw new Error('basePath is required');
if (navigator.storage?.estimate) {
  const { usage, quota } = await navigator.storage.estimate();
  if (quota - usage < MIN_FREE_BYTES) throw new Error('Not enough space for the model');
}

Try / catch

const result = await downloadModel(modelId, basePath, onProgress);
if (!result?.success) {
  // thrown before streaming: DMR not installed, bad modelId, or no space
  showModelError('Model download did not start — verify the DMR tool is installed');
}

Prevention

When it happens

Trigger: The DMR tool/CLI is not installed on the server so it cannot be spawned; an invalid modelId; basePath not writable or out of disk space; any server-side exception raised before the stream begins (all surface as a non-2xx status here).

Common situations: Attempting a model pull before installing the DMR runtime; typo'd model id; storage volume full or read-only; server updated and the DMR invocation contract changed.

Related errors


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

Appendix: 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 3aec848f28)