continuedev/continue · warning · Error

Model '${modelName}' is already being installed.

Error message

Model '${modelName}' is already being installed.

What it means

Thrown by Docker.installModel when a model with the same name already has an in-flight installation tracked in the static Docker.modelsBeingInstalled set. It is a concurrency guard preventing duplicate simultaneous `docker model pull` operations, not an installation failure.

Source

Thrown at core/llm/llms/Docker.ts:174

        .map((line) => line.trim())
        .filter(Boolean);
    } catch (error) {
      console.error("Failed to list Docker models:", error);
      return Object.values(this.modelMap);
    }
  }

  async installModel(
    modelName: string,
    signal: AbortSignal,
    progressReporter?: (task: string, increment: number, total: number) => void,
  ): Promise<any> {
    const targetModel = this.modelMap[modelName] || modelName;

    const release = await Docker.modelsBeingInstalledMutex.acquire();
    try {
      if (Docker.modelsBeingInstalled.has(modelName)) {
        throw new Error(`Model '${modelName}' is already being installed.`);
      }
      Docker.modelsBeingInstalled.add(modelName);
    } finally {
      release();
    }

    try {
      // Report starting the installation
      progressReporter?.(`Installing Docker model ${targetModel}`, 0, 100);

      // Pull the model
      const { stdout, stderr } = await this.executeDockerCommand(
        ["model", "pull", targetModel],
        signal,
      );

      // Report completion
      progressReporter?.(

View on GitHub (pinned to 5522c6f44c)

Solutions

  1. Treat this error as non-fatal: the model is already being installed; await completion and retry use
  2. Dedupe installModel calls behind a shared per-model promise map
  3. Initialize models once sequentially at startup before serving requests
  4. If it persists after installs finish, check that finally-block cleanup isn't skipping (crashed install can leave a stale entry)

Example fix

// before
await Promise.all(models.map(m => docker.installModel(m)));
// after
const pending = new Map();
const installOnce = (m) => pending.get(m) ??= docker.installModel(m).finally(() => pending.delete(m));
await Promise.all(models.map(installOnce));
Defensive patterns

Strategy: try-catch

Validate before calling

const pending = new Map<string, Promise<unknown>>();
function installOnce(docker: Docker, model: string) {
  return pending.get(model) ??= docker.installModel(model).finally(() => pending.delete(model));
}

Type guard

function isDuplicateInstallError(e: unknown): boolean {
  return e instanceof Error && /already being installed/.test(e.message);
}

Try / catch

try { await installOnce(docker, model); }
catch (e) {
  if (isDuplicateInstallError(e)) { await waitForModelReady(docker, model); return; }
  throw e;
}

Prevention

When it happens

Trigger: Two code paths calling installModel(modelName) concurrently before the first finishes: parallel indexing/rerank workers installing the same embedding model, retries racing an in-progress install, or calling installModel inside a loop without awaiting dedupe.

Common situations: Multi-worker startup where each worker pre-installs models, concurrent HTTP handlers both triggering model install, or a frontend retry button racing the first install request.

Related errors


AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27). Data as JSON: /api/errors/4399182357ea1cdd. Report an issue: GitHub.