Zackriya-Solutions/meetily · error

Failed to create model directory

Error message

Failed to create model directory: {}

What it means

Returned by download_model_detailed when fs::create_dir_all fails on the target model directory (models_dir/<name>, e.g. under ~/Library/Application Support/Meetily/models or %APPDATA%\Meetily\models). The active_downloads entry is removed before the error is returned, so the failed attempt does not block retries.

Solutions

  1. Check free disk space - the v3 int8 model needs roughly 670 MB plus buffer
  2. Verify write permission on the models dir (shown by parakeet_get_models_directory / open_parakeet_models_folder) and fix ownership/permissions
  3. If policy or sandboxing blocks the default location, point the app at a writable custom models directory instead of the default
  4. Retry the download after fixing - the failed attempt cleaned up its active-download entry

Example fix

// before
engine.download_model(name, None).await?;

// after - preflight the models dir before downloading
let dir = engine.get_models_directory().await;
let probe = dir.join(".write_test");
tokio::fs::write(&probe, b"x").await
    .map_err(|e| anyhow!("models dir {} not writable: {e}", dir.display()))?;
let _ = tokio::fs::remove_file(&probe).await;
engine.download_model(name, None).await?;
Defensive patterns

Strategy: validation

Validate before calling

// Preflight: writable models dir and enough free space (~700 MB per model)
let dir = engine.get_models_directory().await;
tokio::fs::create_dir_all(&dir).await?; // same op the engine will do
let probe = dir.join(".probe");
tokio::fs::write(&probe, b"x").await?;
let _ = tokio::fs::remove_file(&probe).await;
// check free space via the appropriate platform API before offering the download

Try / catch

match engine.download_model(name, None).await {
    Err(e) if e.to_string().contains("Failed to create model directory") => {
        // surface a dedicated 'check disk space / permissions' message with the dir path;
        // the engine already cleaned its active-download entry, so a retry is safe after fixing
        return Err(e);
    }
    other => other?,
}

Prevention

When it happens

Trigger: The models directory or its parent is read-only or owned by another user; the disk is full; the path is invalid on the platform (restored backup with wrong permissions, sandboxed app container denying writes); corporate policy blocks writes to Application Support/AppData.

Common situations: Disk full before a ~670 MB download starts; permissions broken after migrating user accounts or restoring from backup; macOS app sandbox or managed-device policy denying the Application Support path; OneDrive/Folder-Redirection on Windows making AppData unavailable.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-09-12). Data as JSON: /api/errors/bebe0e207c01ec54. Report an issue: GitHub.

Appendix: source

Thrown at frontend/src-tauri/src/parakeet_engine/parakeet_engine.rs:863

        )
        .await
    }

    async fn download_artifacts(
        &self,
        model_name: &str,
        model_dir: &Path,
        base_url: &str,
        artifacts: &[ArtifactSpec],
        active_download: &ActiveDownload,
        progress_callback: Option<Box<dyn Fn(DownloadProgress) + Send>>,
    ) -> Result<(DownloadProgress, Option<Box<dyn Fn(DownloadProgress) + Send>>)> {
        if active_download.cancellation.is_cancelled() {
            return Err(DownloadCancelled.into());
        }
        fs::create_dir_all(model_dir)
            .await
            .map_err(|error| anyhow!("Failed to create model directory: {}", error))?;

        let client = reqwest::Client::builder()
            .tcp_nodelay(true)
            .pool_max_idle_per_host(1)
            .timeout(Duration::from_secs(3600))
            .connect_timeout(Duration::from_secs(30))
            .build()
            .map_err(|error| anyhow!("Failed to create HTTP client: {}", error))?;
        let total_bytes: u64 = artifacts.iter().map(|artifact| artifact.exact_bytes).sum();
        let download_started = Instant::now();
        let mut confirmed_bytes = 0u64;
        let mut streamed_bytes = 0u64;
        let mut bytes_since_report = 0u64;
        let mut last_report = Instant::now();
        let mut last_percent = 0u8;

        for artifact in artifacts {
            if active_download.cancellation.is_cancelled() {

View on GitHub (pinned to a2cb62e827)