heygen-com/hyperframes · error

Model download failed: ${model}

Error message

Model download failed: ${model}

What it means

Thrown by ensureModel when the whisper model file download completed (downloadFile resolved without throwing) but the model file does not exist at the expected path afterward. This catches the edge case where downloadFile appears to succeed but the file is missing — e.g. a redirect to an error page that wrote nothing, or the file was written to a different location.

Source

Thrown at packages/cli/src/whisper/manager.ts:226

  // 4. Give up — tell the user how
  throw new WhisperUnavailableError(`whisper-cpp not found. Install: ${getInstallInstructions()}`);
}

export async function ensureModel(
  model: string = DEFAULT_MODEL,
  options?: { onProgress?: (message: string) => void },
): Promise<string> {
  const modelPath = join(MODELS_DIR, `ggml-${model}.bin`);
  if (existsSync(modelPath)) return modelPath;

  mkdirSync(MODELS_DIR, { recursive: true });

  options?.onProgress?.(`Downloading model ${model}...`);
  await downloadFile(getModelUrl(model), modelPath);

  if (!existsSync(modelPath)) {
    throw new Error(`Model download failed: ${model}`);
  }

  return modelPath;
}

export function hasFFmpeg(): boolean {
  return findFFmpeg() !== undefined;
}

export { MODELS_DIR, DEFAULT_MODEL };

View on GitHub (pinned to c2996c8626)

Solutions

  1. Check disk space in the models cache directory (~/.cache/hyperframes/whisper/models).
  2. Retry the command — the next attempt will re-download since the file doesn't exist.
  3. Manually download the model from the HuggingFace URL and place it at the expected path.
  4. Verify network connectivity and that huggingface.co is reachable.
Defensive patterns

Strategy: retry

Validate before calling

import { existsSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";

function isModelCached(model: string): boolean {
  return existsSync(join(homedir(), ".cache", "hyperframes", "whisper", "models", `ggml-${model}.bin`));
}

Try / catch

async function ensureModelWithRetry(model: string, maxRetries = 2): Promise<string> {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      return await ensureModel(model);
    } catch (err) {
      if (err instanceof Error && err.message.includes("Model download failed") && i < maxRetries) {
        await new Promise((r) => setTimeout(r, 2000));
        continue;
      }
      throw err;
    }
  }
  throw new Error("Model download failed after retries");
}

Prevention

When it happens

Trigger: downloadFile resolves successfully (HTTP 200, writeStream finished) but existsSync returns false for the model path; the download was interrupted in a way that closed the stream without throwing; a disk error prevented the file from being written; the HuggingFace URL returned an empty or truncated response that was written then removed.

Common situations: Network instability causing a partial download that was cleaned up; disk full; permissions issue on the models cache directory (~/.cache/hyperframes/whisper/models); HuggingFace CDN serving a truncated file.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/b12c384230b7ecdf. Report an issue: GitHub.