Zackriya-Solutions/meetily · error · anyhow::Error

Failed to create models directory

Error message

Failed to create models directory: {}

What it means

Before downloading, the engine runs tokio fs::create_dir_all on the configured models directory; this error means directory creation failed and the appended OS error explains why. No download starts. Typical errnos are PermissionDenied on the parent path or a read-only filesystem.

Solutions

  1. Create the models directory manually and verify the app user can write to it (touch a file there)
  2. Check ownership and permissions on every parent path of the models directory
  3. For packaged/sandboxed builds, confirm the filesystem write entitlement covers the app-data directory
Defensive patterns

Strategy: validation

Validate before calling

// Rust: probe writability before download
async fn models_dir_writable(dir: &Path) -> bool {
    std::fs::create_dir_all(dir).is_ok()
        && std::fs::write(dir.join(".probe"), b"").is_ok()
        && std::fs::remove_file(dir.join(".probe")).is_ok()
}

Try / catch

try {
  await invoke('download_model', { modelName });
} catch (e) {
  if (String(e).includes('Failed to create models directory')) {
    showSetupHelp('Check permissions on the app-data models folder');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Models directory (app-data dir, e.g. ~/Library/Application Support/Meetily/models or %APPDATA%\Meetily\models) is inside a location the process cannot write; a regular file exists at the directory path; sandboxed build without filesystem write entitlements.

Common situations: Corporate lockdown of user profile directories; running the app from a read-only install location; macOS sandbox entitlements missing after packaging changes; models dir redirected to an unmounted volume.

Related errors


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

Appendix: source

Thrown at frontend/src-tauri/src/whisper_engine/whisper_engine.rs:1133

            .await
    }

    async fn download_model_with_owner(
        &self,
        model_name: &str,
        model_url: &str,
        file_path: &PathBuf,
        active_download: &ActiveDownload,
        progress_callback: Option<Box<dyn Fn(u8) + Send>>,
    ) -> Result<()> {
        if active_download.cancellation.is_cancelled() {
            return Err(DownloadCancelled.into());
        }

        if !self.models_dir.exists() {
            fs::create_dir_all(&self.models_dir)
                .await
                .map_err(|e| anyhow!("Failed to create models directory: {}", e))?;
        }

        {
            let mut models = self.available_models.write().await;
            if let Some(model_info) = models.get_mut(model_name) {
                model_info.status = ModelStatus::Downloading { progress: 0 };
            }
        }

        let client = Client::builder()
            .user_agent(concat!("Meetily/", env!("CARGO_PKG_VERSION")))
            .build()
            .map_err(|e| anyhow!("Failed to create download client: {}", e))?;
        let response = tokio::select! {
            biased;
            _ = active_download.cancellation.cancelled() => return Err(DownloadCancelled.into()),
            response = client.get(model_url).send() => response
                .map_err(|e| anyhow!("Failed to start download: {}", e))?,

View on GitHub (pinned to a2cb62e827)